【问题标题】:Problem with handling HTTP HEAD and GET in the same method in Spring在 Spring 中以相同方法处理 HTTP HEAD 和 GET 的问题
【发布时间】:2018-12-07 09:03:12
【问题描述】:

我的 Spring Boot REST 控制器有问题 - 我试图让它在同一个端点同时提供 GET 和 HEAD 方法(理论上应该 - 假设,使方法响应 GET 自动启用 HEAD 作为好)。

问题是我的 GET 方法返回带有正文的响应 - HEAD 绝不应该这样做。因此,当我尝试 HEAD 进入我的端点时,Spring 会打嗝,我完全不知道为什么。

我的控制器方法:

    @RequestMapping(value = "/{ipAddress}", method = RequestMethod.GET)
public HttpEntity<ExitNode> getNode(@PathVariable("ipAddress") String ip) {
    if (validateIp(ip)) {
        if (!nodeCheckerService.checkNodeIp(ip)) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(nodeCheckerService.getNode(ip));
        }
    } else return ResponseEntity.badRequest().build();

}

当我使用格式错误的参数进入端点时,一切正常,我收到 400 Bad Request 并且一切正常。唯一的问题是 GET 返回正文而 HEAD 不应该返回的情况。

编辑:

原来 Postman 是问题所在 - 它没有正确解析响应。安装 Insomnia 并检查端点证明代码是可以的。

【问题讨论】:

  • 为什么不能用映射头方法创建第二个端点?您将有两个类似的方法实现与另一个请求方法。
  • 我一开始尝试这样做,但没有成功。结果是:Resolved [IllegalStateException: Ambiguous handler methods mapped for '/192.42.116.20' 我相信这是由于 HEAD 到启用 GET 的方法的隐式 Spring 映射。

标签: spring rest spring-boot get


【解决方案1】:

启用您的日志记录以向您显示映射。 启用我的后,我会看到以下内容;

要启用日志记录,请将 logging.level.org.springframework.web=TRACE 添加到您的 application.properties

我的 Restful 端点。

@RestController
@RequestMapping("/user")
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value = "/{userId}", method = {RequestMethod.GET, RequestMethod.HEAD})
    public ResponseEntity<User> user(@PathVariable("userId") String userId) {
        return ResponseEntity.ok(this.userService.getUser(userId));
    }

}

查看下面的邮递员屏幕截图,显示对同一端点执行 GET 或 HEAD 并使用相同的 @PathVariable 时成功

获取带有响应正文的请求:

没有响应正文的 HEAD 请求:

【讨论】:

  • 我添加了显式 HEAD 映射,我的跟踪日志如下所示:2018-12-07 11:17:30.543 TRACE 23302 --- [ main] s.w.r.r.m.a.RequestMappingHandlerMapping : c.m.t.c.NodeCheckerController: {[GET, HEAD] /{ipAddress}}: getNode(String) 遗憾的是,邮递员请求仍然失败
  • 在您的日志中检查失败消息。您是否启用了安全性?
  • 这很有趣,在我得到的日志中:o.s.w.s.adapter.HttpWebHandlerAdapter : [3fc8c670] Completed 200 OK, headers={masked} 2018-12-07 11:27:35.643 TRACE 24055 --- [or-http-epoll-3] org.springframework.web.HttpLogging : [3fc8c670] Handling completed 但邮递员给了我错误
  • 还应该有一行带有以下HEAD "/user/3", parameters={}, headers={masked} in DispatcherServlet 'dispatcherServlet',并在其下方有一行带有Mapped to public org.springframework.http.ResponseEntity&lt;com.tut.user.dto.User&gt; com.tut.user.UserController.user(java.lang.String)
  • HTTP HEAD "/192.42.116.20", headers={masked} 2018-12-07 11:27:35.581 DEBUG 24055 --- [or-http-epoll-3] s.w.r.r.m.a.RequestMappingHandlerMapping : [3fc8c670] Mapped to public (blah-blah-blah),但我超过了评论字符限制;) 这是否意味着我的邮递员有问题,而不是我的代码?跨度>
猜你喜欢
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 2019-12-01
相关资源
最近更新 更多