首页 > 解决方案 > 使用 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();
    }
}

标签: restjax-rs

解决方案


通过添加客户端请求和响应过滤器。在响应过滤器中,我使用 EHCache 缓存数据,在请求过滤器中,我正在检查该请求的缓存。


推荐阅读