Creating global initBinder using Spring - java

I am using Spring 3.2 and I am looking for a way that I can force controllers to specify which attributes allowed to be bound, so malicious users can not inject values into bound objects.
Spring recommends using setAllowedFields() to white-list / setDisallowedFields() to black-list.
Instead of doing manually this white-list, I want to do this dinamically, so I want to bound that attributes that are visible on the form.
So is it possible to get this white-list? Is there any way that I can get the visible attributes on the form?
Thanks.

You could implement a RequestDataValueProcessor especially the method processFormFieldValue. You could construct a collection of allowed field names, store this in the session.
Next you would extend the ConfigurableWebBindingInitializer and override the initBinder method. Which would retrieve the collection and pre-configure the WebDataBinder there.
And finally you would need some configuration to wire everything together.
Links
RequestDataValueProcessor javadoc
ConfigurableWebBindingInitializer javadoc

Related

Migrate Struts-Tiles to Spring + tiles 3

I'm migrating to SpringMVC and Apache Tiles 3 from a Strut1 + Tiles project. I know only a little about Struts1+Tiles, it is too old and I'm stuck in Controller and ComponentContext in Struts-tiles. According to document from apache website, it was replaced by ViewPreparer and AttributeContext but I dont know the following line means:
ComponentContext compContext=(ComponentContext)pageContext.getAttribute(ComponentConstants.COMPONENT_CONTEXT,PageContext.REQUEST_SCOPE);
What is ComponentConstants.COMPONENT_CONTEXT? and how to change ComponentContext to AttributeContext
Please Help, Thanks.
Bidi, there are 2 ways of getting an AttributeContext:
The first one, like mck stated: through "org.apache.tiles.AttributeContext.STACK" key of request scope. However, the value is a STACK that contains 2 elements of AttributeContext type. The one we need is the first element. IMHO, this way is limited because since the data structure is a stack, getting also mean removing from the stack according to FIFO rule, so you can use the object for only once.
I am using the second way in my project. Because the execute() method of ViewPreparer already have a parameter of AttributeContext type, and this method is always called each time a page is rendered, so you can use this object to do the thing you want (or put it in request) when overriding the method.
AttributeContext is just a collection of key/value pairs. Normally, people use it to get access to some values which are attributes in the template, so fetching the values and putting them to the request can save the overhead. You can also create some static properties of the inheriting class and setting the values to them.
With the Spring-4 and Tiles-3 integration set up (there's spring docs on this as well as a number of good tutorials around) then the properties you put into spring's model map will be available in your jsps, this is not related to the AttributeContext.
AttributeContext only the other hand is (basically) only for holding the map of attributes. Attributes here are defined within a definition, used to identify template or string attributes (as is typically declared in you xml definitions), and come with properties of role, renderer, expression, and/or value.
If AttributeContext is what you are after: you can get hold of it through the current tilesContainer, and to get hold of the current container use the static TilesAccess, eg
TilesContainer tileContainer = TilesAccess.getCurrentContainer(request);
AttributeContext attributeContext = tilesContainer.getAttributeContext(request);
Bidi,
take a read of http://tiles.apache.org/framework/tutorial/advanced/runtime.html
particular the "Runtime Composition using APIs" section.
TilesContainer container = TilesAccess
.getContainer(request.getSession().getServletContext());
Request tilesRequest = new ServletRequest(
container.getApplicationContext(),
request,
response);
otherwise i suggest you take a dive into the Tiles codebase, it's not complicated code, especially the TilesAccess, Request, ApplicationContext stuff.

Struts2 + spring autowiring actions by-name without exposing certain properties

I am using Struts 2 and Spring autowiring. Right now, the default strategy is set to by-name, but usually we use the constructor and the fallback works to autowire in properties when only one implementing class is available.
There is one property however that I'd like to wire into an action class that has several implementing classes, so I made the Action a java bean, with the properties as fields that can be set. Unfortunately, the only ways that these will be used (apparently) is if they have a public getter/setter, which also exposes them to the type converter at request time. In other words, if a client adds their name to the request as form fields or parameters, Struts will attempt to write those values to them.
So my question is, is it actually possible to use by-name autowiring without exposing properties like that (which may or may not be a security hazard), or am I better off just using XML and defining the Action as an object with scope prototype?
I did eventually track down the documentation for the ParametersInterceptor which actually lists three ways you can limit what parameters are set by the interceptor.
Configuring excludeParams in the parameter configuration, which is a global regex which applies to all actions (not what I want, also possibly deprecated as it is no longer described in the most recent class docs).
Setting excludeMethods (does the same as the previous, the preferred method for global excludes)
Implementing ParameterNameAware, which is the closest to what I wanted. Here you can whitelist what parameters are used.
In the end, defining the action as a prototype object in the normal Spring configuration seemed to be the most prudent. Letting the action manage what parameters it has means another place where parameters need to be explicitly white listed every time a change is made.

What is the purpose of Dynamic Bean in ATG

I've read documentation, but there is no definition of the main purpose of Dynamic Bean. I understand how to implement this but dont know why this approach so good.
So could someone tell the situation when it's good to use Dynamic Bean?
Thanks
Dynamic beans typically allow you to get and set fields which may not be explicit members. The most direct comparison is a map - maps allow you to get and set fields without defining them beforehand. However, a dyanamic bean conforms to standard java idioms (getters/setters).
Unlike a hashmap, however, dyanbeans can enforce constraints more readily (and they hide the underlying data structure implementation, so they can be lazy, or make data connections when being set, etc... ) . For example, you can easily add a getter or setter to your dynabean that is explicit, and the code would read very idiomatically and cleanly interact with other bean apis.
public int getCost()
{
if(this.get("cost")==null)
return -1;
return Integer.parseInt(super.get("cost"));
}
The most useful part about dynamic beans in ATG is providing additional DynamicPropertyMapper classes for classes that aren't already covered by it. First, note that you can use the DynamicBeans.setPropertyValue(object, property, value) and DynamicBeans.getPropertyValue(object, property) static methods to set or get properties on an object that don't necessarily correspond with Java bean properties. If the object you're using isn't registered with dynamic beans, it'll try to use Java bean properties by default. Support is provided out of the box to do that with repository items (properties correspond to repository item properties; also applies to the Profile object, naturally), DynamoHttpServletRequest objects (correspond to servlet parameters), maps/dictionaries (correspond to keys), and DOM Node objects (correspond to element attributes followed by the getters/setters of Node).
To add more classes to this, you need to create classes that extend DynamicPropertyMapper. For instance, suppose you want to make HttpSession objects work similarly using attributes with a fallback to the getters and setters of HttpSession. Then you'd implement the three methods from DynamicPropertyMapper, and the getBeanInfo(object) class can be easily implemented using DynamicBeans.getBeanInfo(object) if you don't have any custom BeanInfo or DynamicBeanInfo classes for the object you're implementing this for.
Once you have a DynamicPropertyMapper, you can register it with DynamicBeans.registerPropertyMapper(mapper). Normally this would be put into a static initialization block for the class you're writing the property mapper for. However, if you're making a property mapper for another class out of your control (like HttpSession), you'll want to make a globally-scoped generic service that simply calls the register method in its doStartService(). Then you can add that service to your initial services.

SpringMVC: Can I specify a #ModelAttribute be populated only for specific controller methods?

We have a couple of attributes that are common to 90% of the pages in our webapp.
I'd like to simply declare an #ModelAttribute("userCredits") on my controller to populate this common attribute.
However, for some pages I don't need this attribute. Can I avoid it being populated (it's modestly expensive to generate) in the one-off cases when it's not required?
I'm not a big fan of it being populated non-declaratively on every call, but I don't like the copy-paste addition of methods in each controller-handler to populate it either.
I'm pretty confident there is no such support, which is also supported by observing the available annotations from the spring javadoc

Custom spring scopes?

Anyone know of any other custom spring scopes than Servlet Context Scope and ThreadScope ?
If you've made some closed-source custom scope I'd really also be interested in hearing what it does and how it worked out for you. (I'd imagine someone would make a WindowScope in a desktop app ?)
I'm open to all use cases, I'm looking to expand my horizon here.
We implemented our own custom Spring scope. A lot of our code works at a relatively low level, close to the database, and we maintain a conceptual level on top of that with its own object model of data sources, links, attributes etc.
Anyway, a lot of beans require a so-called StorageDictionary (an encapsulation of this object graph) to do their work. When we make non-trivial changes to the object graph, the dictionary sometimes needs to be blown away and recreated. Consequently, we implemented a custom scope for objects that were dictionary scoped, and part of the invalidation of a given dictionary involves clearing this custom scope. This lets Spring handle a nice form of automatic caching for these objects. You get the same object back every time up until the dictionary is invalidated, at which point you get a new object.
This helps not only with consistency but also allows the objects themselves to cache references to entities within the dictionary, safe within the knowledge that the cache will be valid for as long as they themselves are retrievable by Spring. This in turn lets us build these as immutable objects (so long as they can be wired via constructor injection), which is a very good thing to do anyway wherever possible.
This technique won't work everywhere and does depend heavily on the characteristics of the software (e.g. if the dictionary was modified regularly this would be horribly inefficient, and if it was updated never this would be unnecessary and slightly less efficient than direct access). However, it has definitely helped us pass off this management of lifecycle to Spring in a way that is conceptually straightforward and in my opinion quite elegant.
In my company we've created two custom scopes, one that will use Thread or Request and another that will use either Thread or Session. The idea is that a single scope can be used for scoped beans without having to change configuration based on the execution environment (JUnit or Servlet container). This also really comes in handy for when you run items in Quartz and no longer have a Request or Session scope available.
Background:
I work on a single web app that runs 4 different web sites under the same servlet context. Each site has its own domain name, e.g. www.examplesite1.com, www.examplesite2.com, etc.
Problem:
Sites sometimes require their own customised instance of a bean from the app context (usually for customised display of messages or formatting of objects).
For example, say sites 1 and 2 both use the "standardDateFormatter" bean, site 3 uses the "usDateFormatter" bean and site 4 uses the "ukDateFormatter" bean.
Solution:
I'm planning on using a "site" scope.
We have a Site enum like this:
enum Site {
SITE1, SITE2, SITE3, SITE4;
}
Then we have a filter that stores one of these Site values in the request's thread using a ThreadLocal. This is the site scope's "conversation id".
Then in the app context there'd be a bean named "dateFormatter", with 'scope="site"'. Then, wherever we want to use a date formatter, the correct one for the user's current site will be used.
Added later:
Sample code here:
http://github.com/eliotsykes/spring-site-scope
Oracle Coherence has implemented a datagrid scope for Spring beans. To sum it up:
A Data Grid Bean is a proxy to a
java.io.Serializable Bean instance
that is stored in a non-expiring
Coherence Distributed Cache (called
near-datagridbeans).
Never used them myself but they seem cool.
Apache Orchestra provides SpringConversationScope.
In a Spring Batch application, we have implemented an item scope.
Background
We have lots of #Service components which compute something based on the current batch item. Many of them need the same workflow:
Determine relevant item parts.
Init stuff based on the item.
For each item part, compute something (using stuff).
We moved the workflow into a base class template method, so the subclasses implement only findItemParts(Item) (doing 1 and 2) and computeSomething(ItemPart) (doing 3). So they became stateful (stuff initialized in findItemParts is needed in computeSomething), and that state must be cleared before the next item.
Some of those services also involve injected Spring beans which are also derived from the current item and must be removed afterwards.
Design
We implemented an AbstractScopeRegisteringItemProcessor which registers the item and allows subclasses to register derived beans. At the end of its process method, it removes the item from its scope context, and the derived beans using DefaultSingletonBeanRegistry.destroySingleton.
How it worked out
It works, but has the following problems:
We did not manage to get the derived beans cleaned up without registration (just based on their #Scope). The concrete processor must create and register them.
AbstractScopeRegisteringItemProcessor would have been nicer using composition and dynamically implementing all interfaces of the underlying processor. But then the resulting #StepScope bean is a proxy for the declared return type (i.e. AbstractScopeRegisteringItemProcessor or ItemProcessor) without the required callback interfaces.
EDIT
With the aid of #Eliot Sykes's solution and shared code plus #Cheetah's BeanDefinition registration, I was able to get rid of the registration as singleton beans. Instead, ItemScopeContext (the storage used by both the processor and the Scope implementation; Java-configured via a static #Bean method) implements BeanDefinitionRegistryPostProcessor. It registers a FactoryBean whose getObject() returns the current item or throws an exception if there is none. Now, a #Component annotated with #Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS) can simply inject the item and need not be registered for end-of-scope cleanup.
So in the end, it did work out well.
A spring locale scope based on the users locale wihtin a web application
See related wiki page
In my company, we have also implemented spring custom scope. We have a multi tenant system where every customer can customize settings. Instance based scope of ours, caches the beans which are customer specific. So each time user of a customer logs in, these settings are cached and reused again when other users of the same customers sign in.
I once used a kind of conversation scope to store some objects in the session scope, in order to keep them when re-entering the same page, but limited to a single page to avoid to leave useless objects in the session. The implementation just stored the page URL and cleaned the conversation scope on each page change.

Categories

Resources