Passing JSON objects in a REST HTTP GET request using Spring MVC

28,504

Solution 1

First create a request bean which should encapsulate the parameters you expect as part of request. Will call it as SomeRequest

Second in the controller use @RequestBody instead of @RequestParam

@ResponseBody public HttpEntity<ParsedRequestOutputObject> parseJsonDataStructures(@RequestBody SomeRequest someRequest) { ... }

Third use RestTemplate as client to invoke your REST services. Sample code below -

SomeRequest someRequest = new SomeRequest();
// set the properties on someRequest
Map<String, String> userService = new HashMap<String, String>();
RestTemplate rest = new RestTemplate();
String url = endPoint + "/parseJsonDataStructures";
ResponseEntity<SomeResponse> response = rest.getForEntity(url, someRequest,
      SomeResponse.class, userService);
SomeResponse resp = response.getBody();

Solution 2

Your statement about only using GET or POST is for REST completely incorrect. The HTTP method used depends on the action you are performing. For retrieval, you are supposed to use a GET, for add/create a POST, for remove/delete a DELETE, and for replace a PUT. Also, to be "true" REST you should only change state through self-documented actions provided by the server response (read up on HATEOAS). Most people don't do the latter.

As an aside, I tried searching for "REST level 2" and also got nothing by sites about beds and Dungeons'and'Dragons. I have personally never heard of it, so it is apparently so new that there are not a lot of sites talking about it or it may be called something else.

To your point about how to send a JSON object, Spring MVC can handle that out-of-the-box. You can read up on it here, which uses the @RequestBody to pull in the entire HTTP request body then parses it using your JSON processor of choice. There are plenty of code samples there describing how to handle lists and such.

Share:
28,504
TPPZ
Author by

TPPZ

Updated on July 12, 2020

Comments

  • TPPZ
    TPPZ almost 4 years

    According to this REST model and to what I think is a consensus on REST: every REST retrieval should be performed as a HTTP GET request. The problem now is how to treat complex JSON objects as parameters in GET requests with Spring MVC. There is also another consensus I found saying "use POST for retrievals!" just because "the big companies do this!", but I have been asked to try to stick to the "REST level 2 rules".

    First question: am I trying to do something that make sense?

    I want to send via GET requests arrays / lists / sets of JSON objects, in Java with Spring MVC. I can not figure out what's wrong with my attempts, I have tried to add/remove double quotes, played around with the URL parameters, but I can not achieve this goal.

    What's wrong with the following code? The code snippet is coming from a MVC controller.

    @RequestMapping(
            value = "/parseJsonDataStructures",
            params = {
                    "language",
                    "jsonBeanObject"
    
            }, method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public HttpEntity<ParsedRequestOutputObject> parseJsonDataStructures(
    
            @RequestParam String language,
            @RequestParam CustomJsonBeanObject[] customJsonBeanObjects){
    
        try {
            ParsedRequestOutputObject responseFullData = customJsonBeanObjectService.parseJsonDataStructures(customJsonBeanObjects, language);
    
            return new ResponseEntity<>(responseFullData, HttpStatus.OK);
        } catch (Exception e) {
            // TODO
        }
    }
    

    I've tried multiple ways to build the URL request (always getting HTTP code 400 Bad Request), this is an example:

    http://[...]/parseJsonDataStructures?language=en&jsonBeanObject={"doubleObject":10, "enumObject":"enumContent", "stringObject":"stringContent"}
    

    The JSON object variables ar of type:

    • Double (not the primitive)
    • enum
    • String

    I am assuming I can pass multiple jsonBeanObject parameters one after the other.

    The jsonBeanObject Java bean is:

    public class CustomJsonBeanObject {
    
        private Double doubleObject;
        private CustomEnum enumObject;
        private String stringObject;
    
        /**
         * Factory method with validated input.
         *
         * @param doubleObject
         * @param enumObject
         * @param stringObject
         * @return
         */
        public static CustomJsonBeanObject getNewValidatedInstance(Double doubleObject, CustomEnum enumObject, String stringObject) {
            return new CustomJsonBeanObject
                    (
                            doubleObject ,
                            enumObject   ,
                            stringObject
                    );
        }
    
        private CustomJsonBeanObject(Double doubleObject, CustomEnum enumObject, String stringObject) {
            this.doubleObject = doubleObject;
            this.enumObject = enumObject;
            this.stringObject = stringObject;
        }
    
    
        public CustomJsonBeanObject() {}
    
        // getter setter stuff
    
        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this);
        }
    }
    
  • TPPZ
    TPPZ almost 10 years
    Thanks for pointing out the "REST retrieval". With "request" I meant "retrieval". So yes, if someone wants to retrieve something via REST they should use an HTTP GET request, not a POST request. I have edited my question highlighting "retrieval" rather than "request".
  • TPPZ
    TPPZ almost 10 years
    Ok, that's good news thanks :) now my questions are: Is there a way to put only some of the input parameters in a "object wrapper"? Could you provide a URL example for the HTTP GET request? So then I can figure out how to call/test it. Basically I can not assume that who is using my REST service is also using Spring (RestTemplate etc.), when I tried to manually write the JSON object in the HTTP GET string I always got some problems regarding URL encoding (e.g. commas), quotes or not quotes etc. Thanks!