我们可以在 Spring REST 中使用单一方法来处理 HTTP POST 和 PUT

Big*_*mAZ 4 spring-mvc spring-web

我们正在构建新的休息服务。我有一个 PUT 方法,看起来像这样:

   @RestController
   public class RestController...
   .
   .
   @PutMapping("/api/entity1")
    public ResponseEntity<String> entity1Put(@RequestBody Myclass entity,
            @RequestParam(value = "node1", defaultValue = emptyString) String node1,
            @RequestParam(value = "user", defaultValue = emptyString) String user,
            @RequestParam(value = "password", defaultValue = emptyString) String password) {...}
Run Code Online (Sandbox Code Playgroud)

该方法本质上是调用应用程序业务层的代理。我的 POST 方法将具有完全相同的签名、准备代码和返回类型。唯一的区别是业务层调用的方法的名称。为了减少代码并促进 API 一致性,我希望有一个方法可以同时处理 PUT 和 POST 请求。

是否有可能做到这一点?

   @RestController
   public class RestController...
   .
   .
   @PutMapping("/api/entity1")
   @PostMapping("/api/entity1")
    public ResponseEntity<String> entity1PutandPost(@RequestBody Myclass entity,
            @RequestParam(value = "node1", defaultValue = emptyString) String node1,
            @RequestParam(value = "user", defaultValue = emptyString) String user,
            @RequestParam(value = "password", defaultValue = emptyString) String password) {...} 
Run Code Online (Sandbox Code Playgroud)

如果是这样,那么我如何确定请求的 HTTP 方法?

Big*_*mAZ 6

看来我因为问了一个愚蠢的问题而收到了“-1”,但这没关系。

这是遵循 @JB Nizet 提供的一些指示后的解决方案。

变化1,改用RequestMapping,方法数组。

更改2,作为Spring的新手,我不知道如果你要求的话,运行时会注入某些类型。添加了 HttpServletRequest 参数,Spring 尽职尽责地提供了我需要的请求数据。

变更 3 更改了我们的业务规则层,以接受方法名称作为参数,从而允许该层实现 PUT 和 POST 之间的语义差异。

因此,将来处理此代码的工程师将更有可能为 PUT/POST 维护一致的 API。这项工作的一个有用的副产品是,除了性能指标之外,我们现在还可以将请求信息推送到我们的应用程序洞察服务中,并且代码仍然很简单。

@RequestMapping(path="/api/entity1", method={RequestMethod.PUT,RequestMethod.POST})
public ResponseEntity<String> entity1PutandPost(@RequestBody Myclass entity1,
        HttpServletRequest request,
        @RequestParam(value = "node1", defaultValue = emptyString) String node1,
        @RequestParam(value = "user", defaultValue = emptyString) String user,
        @RequestParam(value = "password", defaultValue = emptyString) String password) {

    try {
            BusLayer.processObject(request.getMethod(), entity1, creds);
    } 
Run Code Online (Sandbox Code Playgroud)