javax请求对象不评估If-None-Match标头的前提条件

时间:2017-10-27 02:12:23

标签: rest webserver etag javax if-none-match

我在Wildfly中运行REST服务,并且我尝试使用Request.evaluatePreconditions方法生成304 Not Modified响应。

我在请求的If-None-Match标头中传递了一个eTag值,但即使EntityTag与evaluatePreconditions中的值匹配,304方法也不会生成If-None-Match响应标题。

以下是代码:

import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.inject.Inject;
import javax.persistence.PersistenceException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;

import com.mycompany.DataClient;
import com.mycompany.ResponseData;

@Path ("entities")
@Stateless
@TransactionManagement (TransactionManagementType.BEAN)
public class RESTService
{
    @Inject
    private DataClient m_DataClient;

    @GET
    @Produces (MediaType.APPLICATION_JSON)
    public Response findAllEntities (@Context Request request)
    {
        Response.ResponseBuilder response = null;

        try
        {
            ResponseData responseData = m_DataClient.findAll ();

            EntityTag tag = new EntityTag (responseData.getETag ());

            response = request.evaluatePreconditions (tag);

            if (response == null)
            {
                response = Response.status (responseData.getStatusCode ()).entity (responseData.getEntities ()).tag (responseData.getETag ());
            }
        }
        catch (IllegalStateException | PersistenceException | InterruptedException | ExecutionException ex)
        {
            m_Logger.log (Level.SEVERE, "Find All Data Exception", ex);
            response = Response.serverError ();
        }

        return response.build ();
    }
}
  • ResponseData.getStatusCode ()返回与HTTP状态代码对应的int
  • ResponseData.getEntities ()返回List个可序列化对象。
  • ResponseData.getETag ()返回String,其中包含与getEntities返回的实体对象对应的哈希值。

这是我对服务器的请求:

curl -H "Accept:application/json" -H "If-None-Match:7056166173985" -H "Authorization:Bearer adsf" -k -v https://mycompany.com/entities

以下是服务器的响应标头:

< HTTP/1.1 200 OK
< ETag: "7056166173985"
< X-Powered-By: caffeine
< Access-Control-Allow-Credentials: true
< Content-Type: application/json
< Content-Length: 1227
< Date: Fri, 27 Oct 2017 02:00:39 GMT
< Via: 1.1 google
< Alt-Svc: clear
<

如您所见,响应标头中的ETag值与If-None-Match请求标头中的值匹配。为什么我没有收到304 Not Modified回复?

1 个答案:

答案 0 :(得分:0)

我发现了这个问题。问题出在我的代码的另一部分,它将eTag值加载到responseData对象中。因此,responseData.getETag ()方法返回一个包含开始和结束双引号的字符串。我能够通过改变

让事情发挥作用
EntityTag tag = new EntityTag (responseData.getETag ());

EntityTag tag = new EntityTag (responseData.getETag ().replaceAll ("^\"|\"$", ""));

具体来说,我从远程服务器提取数据和相关的eTag,我正在使用Apache HttpClient来检索它们。 以下代码从标题中检索eTag:

private String retrieveETag (HttpResponse response)
{
    Header eTagHeader = response.getLastHeader ("etag");

    if (eTagHeader != null)
    {
        return eTagHeader.getValue ();
    }

    return null;
}

原始eTag标头为ETag: \"etagvalue\"。 我原本希望eTagHeader.getValue ()返回etagvalue,而是返回\"etagvalue\"