当前位置: 首页 > 知识库问答 >
问题:

如何在Jersey客户端中读取有效负载

汪思博
2023-03-14

我这里有个小问题。在触发请求时,我希望使用HMAC对整个消息进行签名,并将生成的签名添加到头中。

所以我实施了

javax.ws.rs.ext.WriterInterceptorContext

在的

public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException

方法I无法访问实体的字符串表示形式。它总是返回一个空字符串。原因似乎是在WriterInterceptor之后执行的MessageBodyWriter。

基本上,我有以下两种情况:

public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
    try {
        final ClientOutputStream stream = (ClientOutputStream) requestContext.getProperty(HTTPCLIENT_ENTITY_STREAM);
        String payload = stream.getString(Charset.forName("UTF-8")); // returns alway empty String
        String signature = doSomeSuffWithPayload(payload);

        MultivaluedMap<String, Object> headers = context.getHeaders();
        headers.add(HmacHeaderValue.X_SIGNATURE.headerName(), signature);
        context.proceed();
    } catch (IllegalArgumentException | ParseException | InvalidKeyException | NoSuchAlgorithmException ex) {
        LOGGER.error(ex.getMessage());
    } catch (UnsupportedEncodingException ex) {
        LOGGER.error(ex.getMessage());
    } catch (IOException ex) {
        LOGGER.error(ex.getMessage());
    }
}

在这里,do某位SuffBackPayload(有效载荷)方法不起作用,因为有效载荷总是空的。

我以为一个小把戏就可以了,所以我换了环境。继续()调用到任何其他位置:

public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
    try {
        context.proceed();
        final ClientOutputStream stream = (ClientOutputStream) requestContext.getProperty(HTTPCLIENT_ENTITY_STREAM);
        String payload = stream.getString(Charset.forName("UTF-8")); // returns the right string representation
        String signature = doSomeSuffWithPayload(payload);

        MultivaluedMap<String, Object> headers = context.getHeaders();
        headers.add(HmacHeaderValue.X_SIGNATURE.headerName(), signature); // doesn't add the header
    } catch (IllegalArgumentException | ParseException | InvalidKeyException | NoSuchAlgorithmException ex) {
        LOGGER.error(ex.getMessage());
    } catch (UnsupportedEncodingException ex) {
        LOGGER.error(ex.getMessage());
    } catch (IOException ex) {
        LOGGER.error(ex.getMessage());
    }
}

在这种情况下,实体的字符串表示形式是ok。但是将头添加到请求中不起作用。

因此,atm我可以将(错误的)签名添加到标题和一个总是空的实体,或者使用正确的实体添加正确的签名,但标题没有添加。

我的问题是:有没有人知道一种通过使用WriterInterceptor来获取实体的字符串表示的方法?

伊迪丝说:

我们使用的是2.25版。泽西岛1号客户。2.27也没有解决问题。

共有1个答案

符允晨
2023-03-14

在深入搜索API后,我发现实体确实是在MessageBodyWriter中的WriterInterceptor之后写入的。除此之外,在MessageBodyWriter中的过程中也会添加头。这就是上述两种方法都不起作用的原因。

我的解决方案atm是建立正确的MessageBodyWriter,并让它序列化实体,就像在WriterInterceptor之后执行的MessageBodyWriter中一样。如果这种情况下不再需要WriterInterceptor,实现Client刚需过滤器就可以了。

import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Providers;

@Context
private Providers providers;

private String getPayloadFromRequest(ClientRequestContext requestContext) throws IOException {
    Object object = requestContext.getEntity();
    if (object != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // buffer into which myBean will be serialized
            Class<Object> type = (Class<Object>) requestContext
                    .getEntityClass();
            GenericType<Object> genericType = new GenericType<Object>(type) {
            };

            // get most appropriate MBW
            final MessageBodyWriter<Object> messageBodyWriter = providers
                    .getMessageBodyWriter(type, type, new Annotation[]{},
                            MediaType.APPLICATION_JSON_TYPE);

            try {
                // use the MBW to serialize myBean into baos
                messageBodyWriter.writeTo(object, object.getClass(),
                        genericType.getType(), new Annotation[]{},
                        MediaType.APPLICATION_JSON_TYPE,
                        new MultivaluedHashMap<String, Object>(), baos);
            } catch (IOException e) {
                throw new RuntimeException(
                        "Error while serializing MyBean.", e);
            }

            return baos.toString();
        } finally {
            baos.close();
        }

    } else {
        return "";
    }
}

代码不是我的,但不幸的是我丢失了源代码。

 类似资料:
  • 我正在尝试创建RESTful web服务,但无法使删除生效,我不确定问题在哪里。我认为问题在客户端项目中,但也可能在服务器项目的资源类中。 我有一个使用这种方法的学生道课,我不认为这是一个问题,因为它适用于其他项目。 我有一个StudentResource类,它是我从包含这段代码的模式中创建的RESTful资源 然后,我创建了一个java项目,并使用此方法创建了名为OneStudent的RESTf

  • 问题内容: 我在JBOSS中有一个客户端服务器通信方案,并且在浏览器中作为客户端( JAVA PROGRAM )。最初在建立连接时,客户端将其证书发送到服务器。服务器从证书中提取客户端的公钥,因此通信将继续。 现在我的问题是 如何将证书(.cer)从客户端发送到服务器? 如何在服务器中接收证书并提取其公钥? 问题答案: 如何将证书(.cer)从客户端发送到服务器? 客户端证书(.cer,.crt,

  • 是否可以使用spring-cloud-consult库从consult k/v存储中重新读取自定义键/值?在文档中还没有找到答案。 当然可以通过http GET请求访问它,但关键是要更改某个键的值,并使spring应用程序立即处理这个更改。 UPD:不幸的是,我们已经从Consult迁移到了config-server,但我想应该能发挥作用。

  • DropWizard在REST的引擎盖下使用泽西。我正在尝试弄清楚如何为我的DropWizard应用程序将公开的RESTfulendpoint编写客户端。 为了这个例子,让我们假设我的DropWizard应用程序有一个< code>CarResource,它为CRUDding cars公开了几个简单的RESTfulendpoint: 因此,我认为结构化的API客户端将类似于: 但是我能找到的关于D

  • 我正在使用泽西restful应用程序。 谁能告诉我为什么它会来,什么是避免它的决心?

  • 我有这个邮戳方法 我使用下面的JSON负载来提出我的帖子请求: 这将返回以下内容: “消息”:“JSON解析错误:无法反序列化超出起始\u数组标记的实例;嵌套异常为com.fasterxml.jackson.databind.exc.MismatchedInputException:无法反序列化超出起始\u数组标记的实例\n位于[源:(PushbackInputStream);行:1,列:1]“,