rest - 使用 JAX-RS 客户端时如何使用 JAX-RS 缓存
问题描述
我正在学习 RESTfull Web 服务。我了解了缓存是如何工作的,并对它们做了一些 POC。用浏览器和邮递员插件测试。但实时任何服务都会被客户端使用,我的意思是java代码。因此,当我们使用 JAX-RS Web 服务客户端时,我无法利用缓存行为。每个请求都表现为新请求。
这是代码
服务代码:
package com.howtodoinjava.demo.rest.service;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import com.howtodoinjava.demo.rest.data.UserDatabase;
@Path("/user-service")
public class UserService
{
@GET
@Path("/users/{id}")
public Response getUserById(@PathParam("id") int id, @Context Request req)
{
CacheControl cc = new CacheControl();
cc.setMaxAge(86400);
Response.ResponseBuilder rb = null;
/*
* Avoid trouble Avoid trouble: The granularity of dates used in HTTP headers is not as
* precise as some dates used in data sources. For example, the precision for a date in a
* database row might be defined to the millisecond. However, the date in an HTTP header
* field is only precise to seconds. When evaluating HTTP preconditions, if you compare a
* java.util.Date object to the date in an HTTP header, the difference in precision might
* produce unexpected results. To avoid this problem, normalize the java.util.Date object
* before comparing to the date value in the HTTP header.
* */
EntityTag etag = new EntityTag(UserDatabase.getLastModifiedById(id).getMinutes()+"");
rb = req.evaluatePreconditions(etag);
if (rb != null)
{
return rb.cacheControl(cc).tag(etag).build();
}
rb = Response.ok(UserDatabase.getUserById(id)).cacheControl(cc).tag(etag);
return rb.build();
}
@PUT
@Path("/users/{id}")
public Response updateUserById(@PathParam("id") int id)
{
UserDatabase.updateUser(id);
return Response.status(200).build();
}
}
客户端代码:
package com.restfullexample.client.cache;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
public class CacheExample {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
client.target("http://localhost:9090/restfullexample/user-service/users/1").request(MediaType.APPLICATION_JSON)
.get();
client.target("http://localhost:9090/restfullexample/user-service/users/1").request(MediaType.APPLICATION_JSON)
.get();
}
}
解决方案
通过添加客户端请求和响应过滤器。在响应过滤器中,我使用 EHCache 缓存数据,在请求过滤器中,我正在检查该请求的缓存。
推荐阅读
- javascript - 在功能组件中使用方法回调测试按钮
- reactjs - 使用 React 的 UseEffect 和事件监听器的区别?
- javascript - Phaser 3中的对撞机随机不起作用
- c++ - 如果它是 OpenCV 垫,我应该释放 std::map 值吗?
- ruby-on-rails - 用于为所有现有 ActiveStorage 变体创建数据库记录的 Rake 任务
- macos - Vim 彻底坏了,不能用
- c# - Microsoft Access 的 OleDbConnection.State 问题
- python - 如何检查是否在 tkinter python 中编辑了文本小部件?
- mysql - mysql上END附近的事件计划错误标记
- java - 在 onComplete 方法中实现接口的问题