How to POST JSON object to spring controller?

2019-07-23 06:10发布

I have spring controller:

@RequestMapping(value = "/add", method = RequestMethod.POST, 
     consumes = "application/json")
public @ResponseBody ResponseDto<Job> add(User user) {
    ...
}

I can POST the object like this with APACHE HTTP CLIENT:

HttpPost post = new HttpPost(url);
List nameValuePairs = new ArrayList();
nameValuePairs.add(new BasicNameValuePair("name", "xxx"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);

In controller I get user with name "xxx"

Now I want to create User object and post it to the server, I tried to use with GSON object like this :

User user = new User();
user.setName("yyy");

Gson gson = new Gson();
String json = gson.toJson(user);

HttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
StringEntity entity = new StringEntity(json.toString(), HTTP.UTF_8);
entity.setContentType("application/json");
httpPost.setEntity(entity);
HttpResponse response = client.execute(httpPost);

But in this way I get in server User object with null fields...

How can I solve it ?

2条回答
甜甜的少女心
2楼-- · 2019-07-23 06:59

Ok a few things you're missing:

  1. Make sure you are serializing and deserializing User to json the same way on the client and server.
  2. Make sure to have jackson libraries on the classpath if you want to use spring built-in jackson support (and preferably use that on the client as well) or include apropriate HttpMessageConverter for Gson. You can use GsonHttpMessageConverter from spring-android for that.
  3. Annotate your request handler method parameter with @RequestBody.
  4. In case of using jackson, as @ararog mentioned, make sure that you specifically exclude fields that can be ingored or annotate the whole User class with @JsonIgnoreProperties(ignoreUnknown = true)
查看更多
做自己的国王
3楼-- · 2019-07-23 07:00

As far as I know, Spring MVC uses Jackson for JSON parsing and serialization/deserialization, jackson usually expects the for a JSON content which has data for all class properties, except those who are marked with JSON ignore, like below:

public class User {

   private String login;
   private String name;
   @JsonIgnoreProperty
   private String password;

   ... getters/setters...
}

So, if you create a instance of User an set only the user name and send this data to server, Jackson will try to deserialize the content to another User object on server side, during the deserialization process he will consider the two mandatory properties login and name, since only name is filled the deserialization is finished and a null reference is returned to the controller.

You have two options:

  1. As an test, set a fake value in all the other properties and send the user data again
  2. Create a Jackson mix-in and add anotations to ignored properties.
查看更多
登录 后发表回答