I have a request(POST or GET), having one variable "data" (coming from Xcode)
now data have assigned JSON object
data={"method":"Auth","action":"login"}
now I have a bean having exactly these two fields(i.e. method,action)
now in Spring controller I have method "login".
I want this method to be invoked based on value in "action" of the request JSON object.
Now, I'm not getting what exactly types of annotation i should use.
Please help..
You need to add Jackson to the classpath, and add <mvc:annotation-driven> to your Spring context, then Spring will automatically register a MappingJacksonHttpMessageConverter for JSON Objects.
Now Annotate your method like this:
#ResponseBody
#RequestMapping("/some/path")
public YourResponseObject someName(#RequestBody YourRequestObject data){
// do something here
}
(Both YourRequestObject and YourResponseObject will be automatically converted to and from JSON, but this works only for POST requests AFAIK)
Related
RPC in Internet transport layer, use dto is reasonable. Http controller? If all controller are used by front end, parameter defined as VO?
I guess you are asking whether the argument of the rest controller method can be a DTO.
Well it will depend on the framework you use. The http parameters are strings.
If the framework has an utility mechanism (probably an annotation) that lets you map the http params you receive into a DTO you supply as the rest controller method arg, there's no problem in the arg being a DTO.
If the framework doesn't have such utility (it just maps each http param into an string arg of the rest controller method), then you have to build manually the DTO in the rest controller method.
I don't know if Spring has such an utility annotation similar to #PathVariable but for gathering multiple request params into a DTO object.
UPDATE:
Spring #RequestBody annotation deserializes the JSON into the java object argument of the rest controller method. So, the arg annotated with #RequestBody is a DTO.
DDD says nothing about which type must be the params of a rest api. They can be either a DTO or Strings, it doesn't matter. If they where strings, you would have to construct the DTO by yourself. Using #RequestBody, Spring framework does it for you.
In java, an object that is carries between process is named following the camel case notation and having the DTO suffix.
e.g. ServiceMessageDTO
DTO stands for data transfer object.
This applies also to the request body parameters from the rest webmethods.
I have seen similar answer here:
Spring MVC: Complex object as GET #RequestParam
Spring map GET request parameters to POJO automatically
I really can't find document of this because this auto mapping is not even done by any annotation. (it doesn't even need #RequestParam in fact)
1) so far I only see simple mapping, the object contain all primitive data, how about if my request is a complicated JSON object which contain several level of attributes (a object contain other objects)? Will the auto-mapping still work?
2) so far I only see Spring controller can take in one auto-map object, can I let it auto-map more than one object? For example:
public #ResponseBody List<MyObject> myAction(MyObject myObject,
MyObject2 myObject2) { ... }
Anyone know where is the document to describe how the mapping work behind the scene? Based on my second question, if Spring allow to do such thing, what if I have same attributes name in MyObject and MyObject2, how the mapping will do?
If you do things like this:
public #ResponseBody List<MyObject> myAction(#RequestBody MyObject myObject) { ... }
Of course you can only have one body in your http request.
As long as you have Jackson in your classpath (spring boot will add this automatically) your objects will be marshalled correctly.
If the JSON in your body is incorrect you will get a 400 (Invalid Request) returned.
Thanks to #RestController I don't need to add annotation #ResposneBody, cause spring knows that it is rest controller, and he will not generate view, but instead it will return json object.
Unfortunately there is one more annotation related to this topic. It is #RequestBody, when controller method accept json object as a parameter. And it will have to be pointed before that parameter.
My question is there a way to get rid of that annotation (#RequestBody).? If my controller is rest controller (#RestController instead of regular #Controller) it should be demanded from spring?
No, you'll have to specify #RequestBody. A Java method can have only a single return value, and so the #ResponseBody is unambiguous, but there are multiple possible ways that mapped controller parameters might be interpreted (in particular, using #ModelAttribute with form encoding is a very common alternative to #RequestBody with JSON), and you'll need to tell Spring how to map the incoming request.
I am using return ResponseEntity of Spring to return HTTP response.
While passing POJO or MAP in entity, it converts that to JSON Object. Like
return new ResponseEntity<Object>(result, HttpStatus.OK);
result may be POJO class. (getter and setters)
I am using
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.GsonHttpMessageConverter ">
</bean>
Now what i want is, i will get a list of response fields in request. I just want to response the request with those fields only.
For Ex, if i receive the response fields as name,id. Then the object must contain those two only.
{
"name":"test",
"id":15
}
i can't able to use #jsonignore or #explore annotations. B'Coz i want the JSON to be done dynamically using coding.
May be by overriding the GSON convertor methods or using AOP.
Is there any way to configure the adapter of jackson to create the object based on the fields.
If you can switch to jackson probably you can use this little extension i wrote for exactly this purpose:
https://github.com/Antibrumm/jackson-antpathfilter
I am using Spring MVC and in my controller, I want to be able to automatically bind incoming parameters to my Java object. It seems like this should be pretty easy to do. The only wrinkle is that the incoming parameter names (e.g. "username") may not match up exactly with the field name in the java object (e.g. "name").
From the Spring documentation (http://static.springsource.org/spring/docs/2.5.6/reference/mvc.html):
"Spring Web MVC allows you to use any
object as a command or form object....
All this means that you don't need to
duplicate your business objects'
properties as simple, untyped strings
in your form objects just to be able
to handle invalid submissions, or to
convert the Strings properly. Instead,
it is often preferable to bind
directly to your business objects. "
How do I actually do this? Any code or links appreciated.
For example, my business object
public class User {
private String username;
private String password;
//getters and setter
}
The request my controller is handling:
example.com/login?name=Steve&pw=1234
I would like to bind "Steve" to User.username and "1234" to User.password.
Thanks.
If I remember correctly, you can override public Object formBackingObject(HttpServletRequest request) and manually setup your command POJO.
In this case you can use custom argument resolver.
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
public Object resolveArgument(final MethodParameter parameter,
final ModelAndViewContainer container,
final NativeWebRequest webRequest,
final WebDataBinderFactory binderFactory) {
final User user = new User();
user.setUsername(webRequest.getParameter("name"));
user.setPassword(webRequest.getParameter("pw"));
return user;
}
}
And in your spring config:
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="your.package.UserArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
example.com/login?username=Steven&password=1234
You can't expect spring MVC to do automatic binding when the property names don't match up. That's just not logical.
EDIT: Do what Kaleb said, overriding formBackingObject is cleaner.
I'll leave this note though:
However, if you have any control over both sides, I strongly recommend making the name consistent. Convention over configuration.
If you want to bind request to the POJO you may need to extend AbstractCommandController or if you have a form - SimpleFormController. I believe you will need the servlet version from org.springframework.web.servlet.mvc package.
use setCommandClass() to setup the correct type of your backing bean in controller constructor, ie POJO:
setCommandClass(User.class);
formBackingBean() used to create new instance of the POJO, that would be used by controller.
controller is responsible for mapping request parameters to the POJO fields.
if mapping is not working good for you, than override formBackingBean() or onBind() methods to read request paratemers and put values to POJO.
You should change your form or your object so that the names match up. If you're trying to use the features in a framework like Spring MVC, you should probably follow their conventions.
Convention over configuration.