JAX-RS如何基于header值匹配同一路径的请求(不使用Spring框架)
实现方案
完全可以在JAX-RS中实现和你给出的Spring代码等价的功能,JAX-RS支持同路径下根据请求头取值匹配不同处理逻辑,以下是标准实现(兼容所有JAX-RS实现,无需依赖额外组件):
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.HeaderParam; import javax.ws.rs.core.Response; // 类级别路径可根据业务调整,Jakarta EE 9+ 替换包名为 jakarta.ws.rs.* @Path("/") public class RequestResource { // 匹配路径/request的所有请求,根据header自动分发 @GET @Path("/request") public Response handleRequest(@HeaderParam("range") String rangeHeader) { if ("include".equals(rangeHeader)) { // 对应Spring中headers={"range=include"}的处理逻辑 SomeObject data = processRequestSomeOther(); return Response.ok(data).build(); } // 对应无指定header的处理逻辑 SomeObject data = processRequest(); return Response.ok(data).build(); } // 你的业务方法实现 private SomeObject processRequestSomeOther() { // 自定义业务逻辑 return new SomeObject(); } private SomeObject processRequest() { // 自定义业务逻辑 return new SomeObject(); } }
如果你使用Jersey(JAX-RS参考实现),可以通过自定义请求过滤器实现和Spring写法一致的注解式路由,无需手动判断header:
- 首先定义绑定注解
import javax.ws.rs.NameBinding; import java.lang.annotation.*; @NameBinding @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface RequireHeader { // 要匹配的header名称 String name(); // 要匹配的header值 String value(); }
- 实现header匹配过滤器
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.ext.Provider; @Provider @RequireHeader(name = "", value = "") public class HeaderMatchFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext ctx) { RequireHeader config = ctx.getUriInfo().getMatchedResourceMethod().getAnnotation(RequireHeader.class); String actualValue = ctx.getHeaderString(config.name()); // header不匹配则跳过当前方法,匹配其他同路径资源方法 if (!config.value().equals(actualValue)) { ctx.setProperty("jersey.config.server.response.setStatusOverSendError", true); ctx.abortWith(Response.status(404).build()); } } }
- 业务代码写法和Spring完全一致
@GET @Path("/request") @RequireHeader(name = "range", value = "include") public Response processWithView() { return Response.ok(processRequestSomeOther()).build(); } @GET @Path("/request") public Response processWithoutView() { return Response.ok(processRequest()).build(); }
注意:如果是POST/PUT等其他HTTP方法,替换方法上的
@GET注解为对应@POST/@PUT即可。
内容的提问来源于stack exchange,提问作者srinannapa
相关产品推荐
相关产品推荐

