0

I'am having a problem with angular 2 http post JSON with multiple attributes to Spring MVC using @RequestParam but it cannot bind to my object, and i try to search around and found there is another way using @ModelAttribute but still getting the same result. Below is my sample code:

Angular 2 (http):

this.http.post('api/codetype-create', JSON.stringify(params), { headers: new Headers({ 'Content-Type': 'application/json' }) })
    .toPromise()
    .then(res => res.json().data)
    .catch(this.handleError);

And the JSON is looks like this:

{
  "test": {
    "ctmCode": "11",
    "ctmMaxLevel": 11,
    "ctmDesc": "test"
  },
  "test2": {
    "param1": "abc",
    "param2": "abc",
    "param3": "abc"
  }
}

Basically I am trying to retrieve "test" and bind to my object in Spring MVC, but it shows null. Below is my spring controller:

@RestController
@RequestMapping("/api")
public class AppController {
  @Autowired
  Mdc_CodeTypeService mdcCodeTypeService;

  @Transactional
  @RequestMapping(value = {"/codetype-create"}, method = RequestMethod.POST)
  public ResponseEntity<String> postCreateCodeType(ModelMap model, HttpServletRequest request, 
                @RequestParam(value="test",required=false) Mdc_CodeType test) {
    try {
      mdcCodeTypeService.createMdcCodeType(test);
    } catch (Exception ex) {
      return new ResponseEntity< String>("failed", HttpStatus.BAD_REQUEST);
    }
    return new ResponseEntity<String>("Success", HttpStatus.CREATED);
  }
}

Update: There is an alternative method suggested by Leon using object wrapper to map with the JSON. I will take it as my second option, but my objective is mapping only "test" attribute to my Mdc_CodeType object using Spring annotation, is that possible?

1 Answer 1

1

You need to bind the body of the request to a variable using @RequestBody. You need an object to capture the entire body.

@RequestMapping(value = {"/codetype-create"}, method = RequestMethod.POST)
public ResponseEntity<String> postCreateCodeType(ModelMap model, HttpServletRequest request, @RequestBody CompleteRequestBody body ) {
  try {
    mdcCodeTypeService.createMdcCodeType(body.getTest());
  } catch (Exception ex) {
    return new ResponseEntity< String>("failed", HttpStatus.BAD_REQUEST);
  }
  return new ResponseEntity<String>("Success", HttpStatus.CREATED);
}

CompleteRequestBody is a hypothetical class that encapsulates everything in the request.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your reply, but with this approach, i might have to build a lot of classes to handle new post data or is this the only way?
Java is a strongly typed language and I would personally recommend having a concrete class for each type of request; however, remember you can still make use of generics and polymorphism to abstract away a lot of the complexity. Alternatively you can make the the Object type a HashMap and access the data that way, but you lose all compile checking on your data
the unmarshaling of your request body is automatically taken care of by spring mvc so you do not have to worry about it. as the answer above correctly states you may either use a concrete class which your request payload is mapped onto (and enjoy the benefits of strongly typed code) or you may use a hash map. if you choose the latter approach it is your own responsibility to fetch the data you need out of the hash map (you may call it "stringly typed code" ;)
Thanks for the help guys. I will be using @RequestBody to map with object wrapper (concrete) approach to handle such requests. It is really such a pain to use hashmap as all the values are in string type since i also using hibernate framework for this project... thanks for the solution :).
Thanks! This also works for JSON strings. If you pass something like JSON.stringify(myObj) from your client, you can receive it with something like public MyObj update(@RequestBody String json) and parse it back to your MyObj with new ObjectMapper().readValue(json, MyObj.class).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.