Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在OkHttp库中使用拦截器_Java_Retrofit_Okhttp_Interceptor - Fatal编程技术网

Java 在OkHttp库中使用拦截器

Java 在OkHttp库中使用拦截器,java,retrofit,okhttp,interceptor,Java,Retrofit,Okhttp,Interceptor,我需要使用所有请求参数生成签名身份验证: 质疑 方法 身体 安全令牌 因此,我编写了一个小型SignatureInterceptor类: public class SignatureInterceptor implements Interceptor { private String token; private String signature = ""; private String method; private String query;

我需要使用所有请求参数生成签名身份验证:

  • 质疑
  • 方法
  • 身体
  • 安全令牌
因此,我编写了一个小型SignatureInterceptor类:

public class SignatureInterceptor implements Interceptor {

    private String token;
    private String signature = "";
    private String method;
    private String query;

    public SignatureInterceptor() {
            this.token = "456456456456";
    }

    @Override
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
            return chain.proceed(originalRequest);
        }

        method = originalRequest.method();
        query = originalRequest.urlString();

        Request authenticatedRequest = originalRequest.newBuilder()
                .method(originalRequest.method(), authenticate(originalRequest.body()))
                .addHeader("signature", signature)
                .build();
        return chain.proceed(authenticatedRequest);
    }

    private RequestBody authenticate(final RequestBody body) {
        return new RequestBody() {
            @Override
            public MediaType contentType() {
                return body.contentType();
            }

            @Override
            public long contentLength() throws IOException {
                return -1;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                BufferedSink authSink = Okio.buffer(sink);
                body.writeTo(sink);

                String data = authSink.buffer().readUtf8();
                signature = generateSignature(method, query, data, token);
                authSink.close();
            }
        };
    }
}
问题是,使用intercetors时,结果在执行过程中是流式传输的,因此在处理签名之前,我无法获取签名值

那么,有没有一种聪明的方法可以在头中插入writeTo()流方法中生成的签名值

根据@Jesse answer更新了代码

private class SignatureInterceptor implements Interceptor {

    @Override
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        String data = "";
        if (originalRequest.body() != null) {
            BufferedSink authSink = new Buffer();
            originalRequest.body().writeTo(authSink);
            data = authSink.buffer().readUtf8();
            authSink.close();
        }
        Request authenticatedRequest = originalRequest.newBuilder()
                .addHeader(HEADER_SIGNATURE, buildSignature(data))
                .build();
        return chain.proceed(authenticatedRequest);
    }
}

您不需要创建自己的RequestBody类;只有在变换身体时才需要这样做


writeTo
方法的内容移动到
intercept
中,以便在调用
继续
之前计算签名。使用该签名添加标题。

您能分享完整的代码吗?我已经更新了答案。非常感谢你,请你也回答我-你的buildSignature方法返回的是什么类型。我面临着在请求中传递签名的问题,我正在尝试Base64编码,但似乎没有多大帮助。提前谢谢。嗨,只是回了一根线,没别的了。