Spring 4.x/3.x (Web MVC) REST API and JSON2 Post requests, how to get it right once for all?

后端 未结 2 1896
北海茫月
北海茫月 2020-11-30 19:45

Before going into details, I know there has been lots of conversations and related questions on Stackoverflow. All of them kind of help me in different ways so I thought I p

相关标签:
2条回答
  • 2020-11-30 20:08

    CURL Post call

    curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add
    

    Different Error Scenarios:

    Here I explore different errors you might come across after you have made a curl call and what might have possibly gone wrong.

    Scenario One:

    HTTP/1.1 404 Not Found
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 949
    Date: Tue, 04 Jun 2013 02:59:35 GMT
    

    This implies that the REST API does not exist in the URL you have provide.

    Root cause:
    • You might have a typo in your request (believe me this can happen)!
    • It could be that your spring configuration is not right. If this is the case it needs further digging into what has actually gone wrong but I have provided some initial actions you need to do before start your more sophisticated investigation.
    Actions:

    After you have made sure that everything is done perfectly right and nothing is wrong with your Configuration nor you URL: - Run a maven clean. - Undeploy your web app or simply delete it. - Redeploy the web app - Make sure to use only one version of Spring in your maven/gradle

    Scenario Two:

    HTTP/1.1 400 Bad Request
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 968
    Date: Tue, 04 Jun 2013 03:08:05 GMT
    Connection: close
    

    The only reason behind this is that fact that your request is not formatted correctly. If you checkout the detailed curl response you should be able to see "The request sent by the client was syntactically incorrect.".

    Root cause:

    Either your JSON format is not right or you are missing a mandatory parameter for the JAVA object.

    Actions:

    Make sure you provide the JSON object in correct format and with the right number of parameters. Nullable properties are not mandatory but you do have to provide data for all NotNullable properties. It is VERY important to remember that Spring is using Java reflection to turn yours JSON file into Java objects, what does this mean? it means that variable and method names are CasE SensItiVe. If your JSON file is sending the variable "userName", than your matching variable in your Java object MUST also be named "userName". If you have getters and setters, they also have to follow the same rule. getUserName and setUserName to match our previous example.

    Senario Three:

    HTTP/1.1 415 Unsupported Media Type
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 1051
    Date: Wed, 24 Aug 2011 08:50:17 GMT
    
    Root cause:

    The Json media type is not supported by your web service. This could be due to your annotation not specifying the media type or you not specifying the media type in Curl post command.

    Actions:

    Check your message convertor is set up correctly and make sure the web service annotation matches the example above. If these were fine, make sure you specify the content-type in your Curl post request.

    The json media type is not supported by your web service.

    Senario N(!):

    HTTP/1.1 200 OK 
    Server: Apache-Coyote/1.1 
    Content-Type: application/json;charset=UTF-8 
    Transfer-Encoding: chunked 
    Date: Tue, 04 Jun 2013 03:06:16 GMT 
    

    Congrats the user is actually send to your server side REST API.

    For further details on how to set up your spring checkout the spring mvc guide.

    Related posts and questions

    This FAQ was not possible if it wasn't for all the people who provided the following posts and questions (this list will expand if I come across useful related posts/questions):

    1. What is the correct JSON content type?
    2. Spring 3.0 making JSON response using jackson message converter
    3. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
    4. Posting JSON to REST API
    5. https://github.com/geowarin/spring-mvc-examples
    6. How to post JSON to PHP with curl
    7. Spring REST | MappingJacksonHttpMessageConverter produces invalid JSON
    8. https://github.com/eugenp/REST
    9. Spring Web MVC - validate individual request params
    10. How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
    11. How do you return a JSON object from a Java Servlet
    12. What MIME type if JSON is being returned by a REST API?
    0 讨论(0)
  • 2020-11-30 20:09

    Should be good to notice that a bean class can NOT be handled if it has 2 or more setter for one field without @JsonIgnore on optional ones. Spring/Jackson throw HttpMediaTypeNotSupportedException and http status 415 Unsupported Media Type.

    Example :

    @JsonGetter
    public String getStatus() {
        return this.status;
    }
    
    @JsonSetter
    public void setStatus(String status) {
        this.status = status;
    }
    
    @JsonIgnore
    public void setStatus(StatusEnum status) {
        if (status == null) {
            throw new NullPointerException();
        }
    
        this.status = status.toString();
    }
    

    Update : We also have to specify @JsonGetter and @JsonSetter in this case, not to have issues when used as return type.

    Just tested it with Spring 3.2.2 and Jackson 2.2. It works fine as parameter (@RequestBody) and/or as return type (@ResponseBody).

    Update 2 :

    If @JsonGetter and @JsonSetter are specified, @JsonIgnore seems not to be required.

    0 讨论(0)
提交回复
热议问题