gpt4 book ai didi

java - 在 JAX-RS Web 服务过滤器中获取 JSON 消息

转载 作者:行者123 更新时间:2023-12-01 10:16:56 32 4
gpt4 key购买 nike

我有一个如下的Web服务方法(部署在WebLogic 12.2.1上),我可以在POJO对象“requestParameters”中接收JSON请求正文:

@POST
@SessionChecker
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("LogIn")
public Response logIn(@Context HttpServletRequest request, Parameters requestParameters) {
....
}

我有一个过滤器,我想在调用上述 Web 服务方法之前拦截请求。

@Provider
@SessionChecker
public class CheckSessionFilter implements ContainerRequestFilter {

@Context
private HttpServletRequest servletRequest;

@Override
public void filter(ContainerRequestContext requestContext) throws WebApplicationException {
....
}

}

在filter()方法中,如何将JSON消息体获取到Parameters类型的POJO对象中?我只需要从 JSON 消息中获取一个属性。过滤器完成后,JSON 消息应不加更改地传递到 Web 服务方法。

提前致谢。

最佳答案

问题就在这里。当您的过滤器被命中时,请求流 (InputStream) 尚未被读取。因此,如果您尝试读取它,那么 Jersey 将无法读取它,因为流只能读取一次,因此它将是空的。

Jersey 实际上为此提供了一个解决方案。 ContainerRequestContext,实际上是 Jersey 特定的 ContainerRequest 的一个实例。 。如果您查看链接的 API,您会发现一个 bufferEntity() 方法。这使我们能够读取该实体,并且 Jersey 将能够再次读取它。所以你的第一步就是调用电话

@Override
public void filter(ContainerRequestContext requestContext)
ContainerRequest cr = (ContainerRequest) requestContext;
cr.bufferEntity();
}

现在您可以获得实体了。如果您查看 ContainerRequest 的 API,也会发现 readEntity(..) 的方法。如果您熟悉 JAX-RS 客户端 API,您可能之前使用过 Response#readEntity(...class) 来读取响应实体。 ContainerRequest#readEntity(..) 的工作方式几乎相同。

因此,如果您知道 JSON 格式应该是什么,并且您有 POJO,那么您就可以这样做

POJO pojo = cr.readEntity(POJO.class);

否则,如果格式因请求而异,您可以将数据提取为 map

Map<String, Object> json = cr.readEntity(new GenericType<Map<String, Object>>(){});
<小时/>

更新

如果您使用的是 JAX-RS API,而不是 Jersey 特定的 API,则上述操作不可行。相反,您需要读取流来获取 JSON,然后将流设置回来,以便 Jersey 可以读取它。如果可能看起来像

InputStream entityIn = requestContext.getEntityStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// write `entityIn` to `baos`
byte[] bytes = baos.toByteArray();
POJO pojo = new ObjectMapper().readValue(bytes, POJO.class);
// do something with POJO
requestContext.setEntityStream(new ByteArrayInputStream(bytes));

当然,您需要一些 JSON 反序列化器来执行此操作。我刚刚在示例中使用了 Jackson。

它不像第一个示例那么优雅,但如果您严格遵守 JAX-RS API,则没有太多选择。如果可以的话,我建议只将 Jersey 依赖项添加到您提供的项目中(编译时),以便您可以使用 API,因为您无论如何都将 Jersey 与 WebLogic 一起使用。

关于java - 在 JAX-RS Web 服务过滤器中获取 JSON 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35840691/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com