1

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

我的控制器调用 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) 返回最终对象

源代码见要点:https ://gist.github.com/2687913

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

有用的链接: http ://blog.42.nl/articles/leveraging-the-spring-mvc-3.1-handlermethodargumentresolver-interface http://stackoverflow.com/questions/6591665/merging-two-objects-in-java

4

1 回答 1

0

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

首先,@ModelAttribute仅在您想将该对象传递给视图时才起作用。

@RequestBody允许 Spring 解析您的输入正文(假设它是 Json)并构建一个 ContentPattern 对象。但是您想从存储库中获取该对象,然后更新相关字段。

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

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

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

然后使用转换器创建 ContentPattern 对象。该对象将填充一些字段,您要更新的字段以及它的标识符。

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

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

使用对象的设置器,使用另一个对象的字段更新存储库中的对象,然后使用同样由 Spring 注入到此类的Validator对其进行验证。

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

我希望这足够清楚!

于 2012-05-10T18:00:40.070 回答