Converting JSON to model object fails while using #JsonProperty - java

The conversion of JSON to a model object fails when #JsonProperty annotation is used as follows:
Controller class snippet:
#RequestMapping( value = "/show", method = RequestMethod.POST)
public String doControl(#ModelAttribute User user, HttpServletRequest request ){
return user.getId();
}
Model class snippet:
public User{
#JsonProperty("user_id")
private id;
#JsonProperty("user_name")
private name;
//getters and setters
}
When I pass an a json {"user_id":1, "user_name":"foo" } with the POST request User fields are null. Will Jsonproperty annotation work while using ModelAttribute annotation?

It will work with #RequestBody. With #RequestBody you specify to Spring MVC that the annotated object is inside HTTP request's body. Spring MVC will then try to decode the object using appropriate HTTPMessageConverter - you want it to use message converter for json, so your POST request should include correct Content-Type header (e.g. Content-Type: application/json).
If you don't specify #RequestBody Spring MVC will try to populate the object using request parameters (e.g. as if you submitted regular HTTP POST form).
Hence:
public String doControl(#RequestBody User user, HttpServletRequest request ){...}

Related

How to unmarshall xml from Http Post Rest Web Service with Jaxb using spring mvc?

My Spring MVC Web Service code is as follows.
Model Class
#XmlRootElement(name="secretData")
public class VData {
private long lKId;
#XmlElement(name="kId")
public long getlKId() {
return lKId;
}
public void setlKId(long lKId) {
this.lKId = lKId;
}
}
Controller Method
#RequestMapping(value = "/vendor", method = RequestMethod.POST)
public String addVendor(#RequestBody VData vData) {
/*Checking recieved value*/
System.out.println(vData.getlKId());//**Returning 0 value **
return "Success";
}
Xml request body for web service
<secretData>
<kId>1</kId>
</secretData>
I am getting "0" value in lKId. Where am I doing wrong. Please provide the correct way to bind the xml element to object member using #XmlElement(name="kId") annotation.
To enable OXM (object to XML mapping) in Spring Web MVC, Spring needs a HttpMessageConverter which can read/write from/to XML. There are several implementations available in Spring using Jackson, XStream, JAXB, ...
Spring should automatically adds a HttpMessageConverter when it detects one of these libraries in the classpath. Do you have the JAXB library on the classpath?
You can also manually register the Jaxb2RootElementHttpMessageConverter as a bean. Through JavaConfig this looks like:
#Bean
public HttpMessageConverter oxmHttpMessageConverter() {
return new Jaxb2RootElementHttpMessageConverter();
}
Add consumes = MediaType.APPLICATION_XML_VALUE inside your #RequestMapping to tell controller that this method will consume xml only.
#RequestMapping(value = "/vendor", method = RequestMethod.POST, consumes = MediaType.APPLICATION_XML_VALUE)
public String addVendor(#RequestBody VData vData) {
/*Checking recieved value*/
System.out.println(vData.getlKId());//**Returning 0 value **
return "Success";
}
And while you are posting xml through http, set header Content-type:application/xml
You have to add #XmlElement annotation on setter and not on getter.
#XmlAttribute annotation has to be put on getter.

Jersey application - 415 unsupported media type

I have jersey application and i could not make form submit success. I get 415 unsupported media type error.
AngularJs:
$http.put(url, frmData, {
transformRequest: angular.identity,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: frmData
});
Java:
#PUT
#Path("/submitform")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void saveForm(#Context HttpServletRequest request,
PojoClass pojoClass) {
}
I get 415 unsupported media type error.
Is there anywhere I am going wrong?
Without some tweeking, Jersey doesn't know how to convert application/x-www-form-urlencoded data into a POJO. The following are what it knows
public Response post(javax.ws.rs.core.Form form)
public Response post(MultivaluedMap<String, String> form)
public Response post(#FormParam("key1") key1, #FormParam("key2") String key)
If you want to use a POJO, you can annotate the POJO parameter with #BeanParam, and annotate the POJO fields with #FormParam
public class POJO {
#FormParam("key1")
private String key1;
#FormParam("key2")
private String key2;
// getters/setters
}
public Response pose(#BeanParam POJO pojo)
If you are using Angular though, you might as well use JSON, as that's the default behavior. You may want to check out this post, if you want to work with JSON.
Add
#Consumes(MediaType.APPLICATION_JSON) in your saveFormMethod
Instead of mapping pojoClass directly as a input parameter, change input parameter as a string and then use gson library to convert string back to actual POJO object.

Extracting parameters from URL with POST method

I have something like this :
#RestController
#RequestMapping("/prop")
public class PropController {
#RequestMapping(method = RequestMethod.POST)
public Prop getProp(#ModelAttribute PropForm propForm) {
//calling methods and stuff using propForm
}
}
My PropForm class :
#Data
public class PropForm {
private String att1;
private String att2;
private String att3;
}
Now I am calling this URL :
http://localhost:8080/prop?att1=blabla&att2=blob&att3=test
I want to extract the parameters from the URL and put them in my propForm.
I've tried replacing #ModelAttribute by #RequestBody and then by #RequestParam. It's still not working, I always get a NullPointerException when running the application.
Please, note that I need to use POST method. I already have it working using GET method
FIRST Make sure you have getters and setters in your PropForm class...
Then, you need to put into your model the Form entity:
model.put("NAME", propForm);
And declare method like this:
#RequestMapping(method = RequestMethod.POST)
public Prop getProp(
#ModelAttribute PropForm propForm
#Valid #ModelAttribute("NAME") PropForm propForm)
// ^ you're missing the name!
{
// do your stuff....
return (Prop) propForm;
}
I think you controller and mapping is ok.
But the problem is you are expecting a post request in the mapping, and you are calling
http://localhost:8080/prop?att1=blabla&att2=blob&att3=test
Now this will generate a GET request Not Post. You cannot send a post request using only url.
If you cant use a form for sending the request then you need to use any 3rd party to generate a POST request
like you can use jquery $.post()
And also att1 att2 will not help unless you bind the object with the model attribute.

How to bind set object to controller in spring

I am trying to make a post call to a controller, but the object I am expecting contains a Set datatype and I am unsure how the post data should look.
Models:
public class Notebook{
private string name;
private Set<Todo> todos;
}
public class Todo{
private String name;
}
Controller
#RequestMapping(method = RequestMethod.POST)
public void createNotebook(Notebook q){
questionnaireService.saveOrUpdateNotebook(q);
}
Currently I have tried posting like the example below:
curl --data "name=some notebook&todos[0].name=todo1&todos[1].name=todo2" http://localhost:8080/api/notebook
Doesn't seem to work. Anyone have experience with Sets?
You should qualify Notebook q with #RequestBody annotation so that the request can be mapped to an object of type Notebook. More about the format of the input data and the converters in Spring MVC doc: Mapping the request body with the #RequestBody annotation.
We send data from the front-end in JSON format and use Jackson JSON to convert it to the Java object. If you go that route, you can directly declare the todos as Set<String> and the input would be
{
name: "some notebook",
todos: ["todo1", "todo2"]
}

How do you handle an Ajax.Request call in a Spring MVC (3.0) app?

I have the following call in my JavaScript:
new Ajax.Request('/orders/check_first_last/A15Z2W2',
{asynchronous:true, evalScripts:true,
parameters:{first:$('input_initial').value,
last:$('input_final').value,
order_quantity:$('input_quantity').value}});
What do I need to do to get Spring MVC (3.0) to handle this?
#Controller
#RequestMapping("/orders")
public OrderController {
#RequestMapping("/check_first_last/{code}")
#ResponseBody
public Result checkFirstLast(#PathVariable String code,
#RequestParam int first,
#RequestParam int last,
#RequestParam("order_quantity") int orderQuantity) {
// fetch the result
Result result = fetchResult(...);
return result;
}
}
A few notes:
#PathVariable gets a variable defined with {..} in the request mapping
#RequestParam is equvallent to request.getParameter(..). When no value is specified, the name of the parameter is assumed (first, last). Otherwise, the value (order_quantity) is obtained from the request.
#ResponseBody means you need Jackson or JAXB present on the classpath, and <mvc:annotation-driven> in the xml config. It will render the result with JSON or XML respectively.
If you want to write HTML to the response directly, you have two options:
change the return type to String and return the HTML as a String variable
add an HttpServletResponse response parameter to the method and use the response.getWriter().write(..) method to write to the response
Resource: Spring MVC documentation

Categories