I'm going to implement a RESTful webservice using Spring. Let it be an ordinary PUT method, something like this:
@RequestMapping(method=RequestMethod.PUT, value="/foo")
public @ResponseBody void updateFoo(@RequestBody Foo foo) {
fooService.update(foo);
}
In such a case input JSON format (if it corresponds to Foo class) will be successfully converted to Foo instance with no extra efforts, or error will be issued in case of wrong format. But I'd like to make the service able to consume two different types of formats using same method (e.g. PUT) and same URL (e.g. /foo).
So that it possibly looked like:
//PUT method #1
@RequestMapping(method=RequestMethod.PUT, value="/foo")
public @ResponseBody void updateFoo(@RequestBody Foo foo) {
fooService.update(foo);
}
//PUT method #2
@RequestMapping(method=RequestMethod.PUT, value="/foo")
public @ResponseBody void updateFoo(@RequestBody FooExtra fooExtra) {
fooService.update(fooExtra);
}
and Spring converter tried to convert input JSON not only in Foo but in FooExtra as well and invoked corresponding PUT method depending on input format.
In fact, I tried to implement it exactly as it described above but without success. Is it even possible? Maybe, I need some kind of "trick"? What is the best (and the most proper) way to achieve such behavior? Of course, I could always make two different URLs but I'd like to know whether it is possible with the same one.
The class App implements CommandLineRunner and calls the SpringApplication. run() method by passing this instance of class App. class. This will, in turn, call the run method, where we have code to call a RESTful Web Service and consume JSON response using RestTemplate class of Spring framework.
The REST architecture allows API providers to deliver data in multiple formats such as plain text, HTML, XML, YAML, and JSON, which is one of its most loved features.
The Rest Template is the central Spring class used to create applications that consume RESTful Web Services. You can use the methods available in the Rest Template class to consume the web services for all HTTP methods.
Your attempt didn't work simply because Spring tried to match your methods against the request, by looking at url and method type, which are in both cases the same. It does not work like overloading in Java; argument types do not differentiate your methods.
But there are good news. SpringMVC can also examine request headers and request parameters when trying to match your handler methods. Since what you want to pass is actually pure metadata -an alternative format type of the same information- it makes perfect sense to use a custom request header. It's very easy to add custom headers when using a rest api. See the following link for JAX-RS: Adding a custom header.
Now in your server side you should configure the handler methods as:
//PUT method #1
@RequestMapping(method=RequestMethod.PUT, value="/foo", headers="returnType=Foo")
public @ResponseBody Foo updateFoo(@RequestBody Foo foo) {
fooService.update(foo);
}
//PUT method #2
@RequestMapping(method=RequestMethod.PUT, value="/foo", headers="returnType=FooExtra")
public @ResponseBody FooExtra updateFoo(@RequestBody FooExtra fooExtra) {
fooService.update(fooExtra);
}
Note also that if you want to access a return value with @ResponseBody you have to return your object, otherwise make the methods void
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With