Is it possible to give Spring MVC's form binding some kind of type hint to indicate what class to instantiate and populate with form data?
I've got some quite unusual requirements to try and build a dynamic form, that represents a collection of different objects. The user can add objects from a selection of types to this collection, and then set the properties for that object type using form elements. I can figure out how to create the form using jQuery, but I'm not sure how to get Spring to handle a load of POST data when it won't know what types to bind to in advance.
One way that I can think of doing this is to write your own custom HandlerMethodArgumentResolver , which is responsible for translating the request into the argument values of the controller methods. You should be able to create a custom annotation that will indicate to Spring MVC, that your custom handler method argument resolver will be resolving the specific annotated method arguments(say #CustomType Object argument).
Once the call comes into the handler resolver, you can probably determine the type that the json request should map to, and call the json mapper with the actual type.
You can register a custom argument resolver this way:
<annotation-driven>
<argument-resolvers>
<beans:bean class="..CustomArgumentResolver"/>
</argument-resolvers>
</annotation-driven>
Related
I'm using spring mvc.
I have created the controller, view, pojo, dao.
Now I have the need to create an object composted from multiple objects pojo, is the case of creating a DTO?
If you're looking to build a composite kind of Object for view purposes only, then there is a good argument for a DTO. If the composite is just an aggregation of the POJOs you can use org.springframework.ui.Model and just add attributes inside your Controller. If there is logic and business rules that need to be applied, it is probably best to do this in a Service layer that sits between your Controller and your DAO.
If you mean that you need to access properties of few POJOs on the client side and you want to reduce amount of calls from
client to server then yes. It is better to create a DTO object where place only necessary properties from POJOs that you will
use on client side. And return this DTO as a result of a single call from client to server.
I need to the ignore the serialization (JSon/Jackson and XML/XStream) of some attributes from my object response based on user input/or Spring security roles (like you don't have permission to see the content of this field, but all others are ok etc). How is the best approach to do this in Spring MVC Rest?
Other approach is show only the attributes that are relevant for the api user, like described here http://googlecode.blogspot.com.br/2010/03/making-apis-faster-introducing-partial.html
If you are using Jackson, here are some possible options to modify the Json serialization:
Use the #JsonIgnore annotation - However, this is static filtering, and will not allow you to implement rule-based filtering as you appear to need
Use #JsonFilter - This will allow you to implement an interface in which you can provide your serialization filtering logic. You may find this to be too heavyweight of a solution.
The way I often solve this is to return a Map from my Controller methods instead of the underlying object. You can write processing code that puts the relevant fields from the object into the Map, therefore giving you complete control over what is serialized. You could include a method on the Object to do the conversion. The method could look something like this:
// RequestObj is whatever 'input' object that indicates what should be filtered
public Map<String,Object> convertToMapForRequest(RequestObj request){
// Build return map based on 'this' and request
}
I.e. I only want a nice way to retrieve existing objects from my Model (mostly some SessionAttributes).
I don't want new objects to be created and I especially don't want objects to be instantiated from request parameters and put into the model. This just sounds like a back door to me.
It would also be great if an Exception can be thrown if no matching parameter is in the model.
I got the answer to this by reading the source code. According to the implementation of org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveModelAttribute, a new bind Object will not be created if the name of the model attribute is declared as a session attribute using the #SessionAttributes annotation.
If the attribute is not present in the session, an Exception will be thrown.
So it is relatively safe to bind session attributes this way.
I am using struts 1.3. I have a an action I am reusing in 3 different cases. The form bean backing this has a property that has the complete path(passed from the jsp) to which the action should forward in case of success/failure(the path is different for each case depending on what the user is doing). How do I specify this for the input attribute of the action in the struts config to read from that form bean property.
What you can do is return a dynamic ActionForward from your Action class. This lets you use an ActionForward that isn't defined in yourstruts-config.xml
return new ActionForward(path_to_forward, redirect_true_or_false);
This doesn't help you for the input, which expects a JSP and not an ActionForward, but you should be able to do that in the ActionForm's validate() method. The first parameter passed into that method is an ActionMapping. On that object, you should be able to call setInput(String) with the path of your JSP. I have not tried this, but it looks like it should work.
I found that, by default when I using Spring MVC, "2010/01/02" binds correctly, but "2010-01-02" does not.
I know Spring has some useful binding mechanisms like initBinder. However, in this question I want to know where is the rule defined. Does anyone know that for example RFC documents of HTTP or Spring references.
It's just coincidence.
Spring MVC can implicitly convert input parameters to model objects via their single-argument constructor that takes String (if model objects have such constructors). Date has this constructor, though it's deprecated, so that this behaviour is determined by behaviour of that constructor.