如何在现有JAX-RS接口中实现基于If-Modified-Since的HTTP条件GET?
如何在JAX-RS GET接口中实现If-Modified-Since条件请求
我来给你一步步拆解怎么实现这个If-Modified-Since的条件GET请求,核心逻辑就是对比客户端请求头里的时间和资源的最后修改时间,以此决定返回304(资源未更新)还是正常的200响应:
关键步骤说明
- 注入HttpHeaders获取请求头:首先要在方法参数里加入
@Context HttpHeaders headers,这样就能拿到客户端发送的If-Modified-Since请求头。 - 获取资源的最后修改时间:假设你的
Details实体类有getLastModified()方法(或者你可以从DAO层直接获取这个时间),这个时间是判断资源是否更新的核心依据。 - 时间对比与响应处理:
- 如果客户端没带
If-Modified-Since头(比如第一次请求),直接返回正常响应,并带上Last-Modified头。 - 如果资源的最后修改时间不晚于请求头里的时间,说明资源没有更新,直接返回
304 Not Modified,不需要返回实体内容。 - 如果资源有更新,返回正常的200响应,同时设置
Last-Modified响应头,让客户端下次请求时携带这个时间。
- 如果客户端没带
修改后的完整代码示例
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.HttpHeaders; import java.util.ArrayList; import java.util.Date; @GET @Path("{id}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response getDetails(@PathParam("id") Integer id, @Context HttpHeaders headers) { Details details = dao.getDetails(id); if (details == null) { // 资源不存在,返回404 return Response .status(Response.Status.NOT_FOUND) .entity("<detailsNotFound />") .build(); } // 获取资源的最后修改时间(假设Details实体提供了该方法) Date lastModified = details.getLastModified(); // 从请求头中提取If-Modified-Since时间,处理可能的空值 Date ifModifiedSince = null; if (headers.getRequestHeader(HttpHeaders.IF_MODIFIED_SINCE) != null && !headers.getRequestHeader(HttpHeaders.IF_MODIFIED_SINCE).isEmpty()) { ifModifiedSince = headers.getRequestHeader(HttpHeaders.IF_MODIFIED_SINCE).get(0); } // 对比时间:如果资源未修改,直接返回304 if (ifModifiedSince != null && !lastModified.after(ifModifiedSince)) { return Response.notModified().build(); } // 资源已修改,继续构建响应内容 details.setLink(new ArrayList<Link>()); Link linkSelf = new Link(); linkSelf.setRel("self"); // 补全self链接的地址(比如通过uriInfo获取当前请求路径) // linkSelf.setHref(uriInfo.getAbsolutePath().toString()); details.getLink().add(linkSelf); // 返回200响应,并设置Last-Modified头供客户端下次使用 return Response.ok(details) .lastModified(lastModified) .build(); }
注意事项
- 要确保
Details实体的getLastModified()返回的时间是准确的,比如从数据库的update_time字段同步获取。 - 必须处理
ifModifiedSince为null的情况(客户端第一次请求时不会携带这个头),此时直接走正常响应逻辑。 lastModified.after(ifModifiedSince)是判断资源是否更新的核心:如果资源的最后修改时间在请求头时间之后,说明有更新,返回200;否则返回304。
内容的提问来源于stack exchange,提问作者Jay1995
相关产品推荐
相关产品推荐

