Spring REST控制器部分更新现有资源

时间:2012-05-10 13:34:28

标签: java spring rest

我想对资源执行部分更新。我有一个想法,我可以组合@ModelAttribute(加载现有资源)和@RequestBody用提供的字段填充它,然后运行@Valid。据我所知,@ModelAttribute在其他任何事情之前被调用。

My Controller调用ModelAttribut并使用我的ContentPatternConverter正确创建ContentPattern实体。虽然在那之后我想用@RequestBody提供的字段填充“模式”,然后检查它是否有效。虽然我的ContentPattern在通过ModelAttribute创建后没有填充RequestBody。

@RequestMapping(value = "/patterns/{id}", method = RequestMethod.PUT, produces = "application/json")
@ResponseBody
public ResponseEntity<ContentPattern> updateContentPattern(Principal principal, @ModelAttribute("id") @RequestBody ContentPattern pattern) { //implementation }

任何想法如何使用我的方法解决这个问题,或者是否有另一个(更好的)解决方案?

更新1

经过一番研究后,我提出了以下解决方案。

  1. 创建了我自己的注释@RequestBodyPathVariable
  2. 编写了实现HandlerMethodArgumentResolver的RequestBodyPathVariableMethodArgumentResolver。它的作用是1)基于URI路径变量(例如patterns / {id})从自定义转换器获取现有资源。 2)从请求主体创建一个对象。 3)合并现有和提供的资源。 4)验证最终对象。 5)返回最终对象
  3. 请参阅要点:[{3}}

    (其他情况可能需要更好的/其他合并方法。)

    有用的链接: https://gist.github.com/2687913 http://stackoverflow.com/questions/6591665/merging-two-objects-in-java

1 个答案:

答案 0 :(得分:0)

我正在考虑这个问题,这就是我要做的事(免责声明,我没试过):

首先,@ModelAttribute仅在您要将该对象传递给视图时才会提供。

@RequestBody允许Spring解析你的输入体(让我们说它是Json)并构建一个ContentPattern对象。但是您希望从存储库中获取该对象,然后更新相关字段。

首先,我将创建WebArgumentResolver的实现。使用MethodParameter检查它是否来自ContentPattern类。此实现将作为依赖注入接收,用于创建ContentPattern对象的HttpMessageConverter

然后您从HttpInputMessage创建NativeWebRequest,如下所示:

return new ServletServerHttpRequest((HttpServletRequest)nativeWebRequest.getNativeRequest());

然后使用Converter,创建ContentPattern对象。此对象将填充一些字段,您要更新的字段以及其标识符。

使用标识符,存储库或EntityManager持久化上下文(都由Spring注入到类),您可以从存储库中获取对象。

现在您有两个ContentPattern对象,从存储库获取的对象,以及从请求正文创建的对象。

使用对象的setter,使用另一个对象的字段从存储库更新对象,然后使用Spring注入此类的Validator验证它。

如果一切正常,可选择将更新的对象保存为持久性,并将其用作resolverArgument方法的返回值。

我希望这很清楚!