javax 请求 object 未评估 If-None-Match header 的先决条件
javax Request object not evaluating precondition for If-None-Match header
我是 运行 Wildfly 中的 REST 服务,我正在尝试使用 Request.evaluatePreconditions
方法生成 304 Not Modified
响应。
我在请求的 If-None-Match
header 中传递了一个 eTag 值,但是即使 EntityTag 匹配该值,evaluatePreconditions
方法也没有生成 304
响应在 If-None-Match
header.
代码如下:
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 ()
returns 对应于 HTTP 状态代码的 int
。
ResponseData.getEntities ()
returns 可序列化的 List
objects.
ResponseData.getETag ()
returns 包含与 getEntities
. 返回的实体 objects 相对应的散列的 String
这是我对服务器的请求:
curl -H "Accept:application/json" -H "If-None-Match:7056166173985" -H "Authorization:Bearer adsf" -k -v https://mycompany.com/entities
这是服务器的响应 header:
< 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
<
如您所见,响应 header 中的 ETag 值与 If-None-Match
请求 header 中的值匹配。为什么我没有收到 304 Not Modified
回复?
我发现了问题。问题出在我的代码的另一部分,它将 eTag 值加载到 responseData
object。因此,responseData.getETag ()
方法是 returning 一个包含开始和结束双引号的字符串。我可以通过更改
来让事情正常进行
EntityTag tag = new EntityTag (responseData.getETag ());
至
EntityTag tag = new EntityTag (responseData.getETag ().replaceAll ("^\"|\"$", ""));
具体来说,我正在从远程服务器中提取我的数据和关联的 eTag,并且我正在使用 Apache HttpClient 来检索它们。
以下代码从 header:
检索 eTag
private String retrieveETag (HttpResponse response)
{
Header eTagHeader = response.getLastHeader ("etag");
if (eTagHeader != null)
{
return eTagHeader.getValue ();
}
return null;
}
原始电子标签 header 是 ETag: \"etagvalue\"
。
我原本期望 eTagHeader.getValue ()
到 return etagvalue
,但结果却是 returns \"etagvalue\"
.
我是 运行 Wildfly 中的 REST 服务,我正在尝试使用 Request.evaluatePreconditions
方法生成 304 Not Modified
响应。
我在请求的 If-None-Match
header 中传递了一个 eTag 值,但是即使 EntityTag 匹配该值,evaluatePreconditions
方法也没有生成 304
响应在 If-None-Match
header.
代码如下:
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 ()
returns 对应于 HTTP 状态代码的int
。ResponseData.getEntities ()
returns 可序列化的List
objects.ResponseData.getETag ()
returns 包含与getEntities
. 返回的实体 objects 相对应的散列的
String
这是我对服务器的请求:
curl -H "Accept:application/json" -H "If-None-Match:7056166173985" -H "Authorization:Bearer adsf" -k -v https://mycompany.com/entities
这是服务器的响应 header:
< 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
<
如您所见,响应 header 中的 ETag 值与 If-None-Match
请求 header 中的值匹配。为什么我没有收到 304 Not Modified
回复?
我发现了问题。问题出在我的代码的另一部分,它将 eTag 值加载到 responseData
object。因此,responseData.getETag ()
方法是 returning 一个包含开始和结束双引号的字符串。我可以通过更改
EntityTag tag = new EntityTag (responseData.getETag ());
至
EntityTag tag = new EntityTag (responseData.getETag ().replaceAll ("^\"|\"$", ""));
具体来说,我正在从远程服务器中提取我的数据和关联的 eTag,并且我正在使用 Apache HttpClient 来检索它们。 以下代码从 header:
检索 eTagprivate String retrieveETag (HttpResponse response)
{
Header eTagHeader = response.getLastHeader ("etag");
if (eTagHeader != null)
{
return eTagHeader.getValue ();
}
return null;
}
原始电子标签 header 是 ETag: \"etagvalue\"
。
我原本期望 eTagHeader.getValue ()
到 return etagvalue
,但结果却是 returns \"etagvalue\"
.