在Spring RESTful服务中使用相同的URL和相同的方法来使用不同的输入JSON格式

时间:2014-11-17 13:03:37

标签: java json spring rest spring-mvc

我将使用Spring实现RESTful Web服务。 让它成为普通的PUT方法,如下所示:

@RequestMapping(method=RequestMethod.PUT, value="/foo")
public @ResponseBody void updateFoo(@RequestBody Foo foo) {
    fooService.update(foo);
}

在这种情况下,输入JSON格式(如果它对应于Foo类)将成功转换为Foo实例而不需要额外的努力,否则在格式错误的情况下将发出错误。 但我想使服务能够使用相同的方法(例如PUT)和相同的URL(例如/ foo)使用两种不同类型的格式。

所以它可能看起来像:

//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);
}

并且Spring转换器尝试转换输入JSON,不仅在Foo中,而且在FooExtra中,并根据输入格式调用相应的PUT方法。

事实上,我试图按照上面描述的方式实现它,但没有成功。它甚至可能吗?也许,我需要某种“技巧”? 实现这种行为的最佳方式(也是最合适的方式)是什么?当然,我总是可以创建两个不同的URL,但我想知道是否可以使用相同的URL。

2 个答案:

答案 0 :(得分:6)

你的尝试不起作用只是因为Spring试图通过查看url和方法类型来匹配请求,这两种情况都是相同的。它不像Java中的重载那样工作;参数类型不区分您的方法。
但有好消息。 SpringMVC还可以在尝试匹配处理程序方法时检查请求标头和请求参数。由于您要传递的内容实际上是纯元数据 - 相同信息的替代格式类型 - 因此使用自定义请求标头非常有意义。使用rest api时,添加自定义标头非常容易。请参阅以下JAX-RS链接:Adding a custom header

现在在服务器端,您应该将处理程序方法配置为:

//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);
}

另请注意,如果要使用@ResponseBody访问返回值,则必须返回对象,否则使方法无效

答案 1 :(得分:0)

为了理解它,我们应该考虑Spring如何工作,它使用Dispatcher Servlet。我不认为春天会为不同类型的输入“结合”工作。

所以我的回答是:“技巧”,有两个不同的网址;)