Java Jersey的响应授权

Java Jersey的响应授权,java,json,jersey,jax-rs,Java,Json,Jersey,Jax Rs,我有一个Jersey 2应用程序,其中包含使用和生成json的资源。我的要求是将签名添加到由各种响应数据组合生成的授权响应头(类似于AmazonWebServices请求签名)。其中一部分数据是响应体,但我看不到有任何过滤器或拦截点允许我访问json内容。我想这主要是因为响应outputstream用于写入而不是读取 关于我如何阅读回应体或其他方法,有什么想法吗 谢谢。您可以实现以访问内容,并且在完成拦截逻辑后,将其转发给请求。例如 import java.io.*; import com.s

我有一个Jersey 2应用程序,其中包含使用和生成json的资源。我的要求是将签名添加到由各种响应数据组合生成的授权响应头(类似于AmazonWebServices请求签名)。其中一部分数据是响应体,但我看不到有任何过滤器或拦截点允许我访问json内容。我想这主要是因为响应outputstream用于写入而不是读取

关于我如何阅读回应体或其他方法,有什么想法吗

谢谢。

您可以实现以访问内容,并且在完成拦截逻辑后,将其转发给请求。例如

import java.io.*;

import com.sun.jersey.api.container.ContainerException;
import com.sun.jersey.core.util.ReaderWriter;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;


public class ExampleFilter implements ContainerRequestFilter {

    @Override
    public ContainerRequest filter(ContainerRequest req) {

        try(InputStream in = req.getEntityInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
            if (in.available() > 0) {
                StringBuilder content = new StringBuilder();
                ReaderWriter.writeTo(in, out);

                byte[] entity = out.toByteArray();            
                if (entity.length > 0) {
                    content.append(new String(entity)).append("\n");
                    System.out.println(content);
                }

                req.setEntityInputStream(new ByteArrayInputStream(entity));
            }

        } catch (IOException ex) {
            //handle exception
        }

        return req;

    }

}

我的理解是,当应用程序响应请求时,您希望通过在其值中添加签名来修改
授权

如果是这种情况,您希望实现一个
ContainerResponseFilter

public class MyContainerResponseFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
        // You can get the body of the response from the ContainerResponseContext
        Object entity = containerResponseContext.getEntity();
        // You'll need to know what kind of Object the entity is in order to do something useful though
        // You can get some data using these functions
        Class<?> entityClass = containerResponseContext.getEntityClass();
        Type entityType = containerResponseContext.getEntityType();

        // And/or by looking at the ContainerRequestContext and knowing what the response entity will be
        String method = containerRequestContext.getMethod();
        UriInfo uriInfo = containerRequestContext.getUriInfo();

        // Then you can modify your Authorization header in some way
        String authorizationHeaderValue = containerResponseContext.getHeaderString(HttpHeaders.AUTHORIZATION);
        authorizationHeaderValue = authorizationHeaderValue + " a signature you calculated";
        containerResponseContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION, authorizationHeaderValue);
    }
}
公共类MyContainerResponseFilter实现ContainerResponseFilter{
@凌驾
公共无效筛选器(ContainerRequestContext ContainerRequestContext、ContainerResponseContext ContainerResponseContext)引发IOException{
//您可以从ContainerResponseContext获取响应的主体
对象实体=containerResponseContext.getEntity();
//为了做一些有用的事情,您需要知道实体是什么类型的对象
//您可以使用这些函数获取一些数据
类entityClass=containerResponseContext.getEntityClass();
类型entityType=containerResponseContext.getEntityType();
//和/或查看ContainerRequestContext并了解响应实体将是什么
String方法=containerRequestContext.getMethod();
UriInfo UriInfo=containerRequestContext.getUriInfo();
//然后,您可以通过某种方式修改授权标头
String authorizationHeaderValue=containerResponseContext.getHeaderString(HttpHeaders.AUTHORIZATION);
authorizationHeaderValue=authorizationHeaderValue+“您计算的签名”;
containerResponseContext.getHeaders().putSingle(HttpHeaders.AUTHORIZATION,authorizationHeaderValue);
}
}

请注意,即使Jersey找不到与请求路径匹配的资源,也会为应用程序的所有请求调用
过滤器
函数,因此,您可能需要做一些额外的检查。

非常感谢您的回答@oggmonster-我遇到了ContainerResponseFilter,但在我看来,它在转换为json之前只给了我实体对象。我有点想在签名中使用响应体的json版本,因为这将是客户端可以用来生成签名进行比较的内容。所有截取点似乎都在实体被呈现为json之前。为什么它必须是json?如果你有一个Jackson正在编组的对象,但它还没有被编组,只需将它投射到你的对象上,然后从那里得到你需要的东西。如果这不是一个选项,那么在创建响应时将对象显式序列化为JSON,然后在
ContainerResponseFilter
中将实体作为字符串读取。我已经在资源中创建了json并在那里生成了签名。感谢您的回复,但我正在尝试向响应添加授权头,以便客户端可以信任来自有效服务器的授权头。