REST客户端Content-Type标头抛出UnsupportedOperationException

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了REST客户端Content-Type标头抛出UnsupportedOperationException相关的知识,希望对你有一定的参考价值。

我正在开发一个REST客户端来连接到我无法访问的外部服务器。我已经能够使用Postman和SOAPUi成功地建立通信,现在我正在尝试使用Java(org.glassfish.jersey.client.ClientResponse),但无济于事,因为每当我包含“Content-type:application / json“标题,我得到一个例外,如果我不包含此标题,我会收到415错误(不支持的媒体类型),我认为这要求我包含Content-Type标题。

这是标题准备:

Client client = ClientBuilder.newClient();

MultivaluedMap<String, Object> headerMap = new MultivaluedHashMap<String, Object> ();

String username="admin";
String password="admin";
String usernameAndPassword = username + ":" + password;
String authorizationHeaderValue = "Basic " + java.util.Base64.getEncoder().encodeToString( usernameAndPassword.getBytes() );
headerMap.put("Authorization", Arrays.asList(new Object [] { authorizationHeaderValue }));
//headerMap.put("Content-Type", Arrays.asList(new Object [] { "application/json" }));
headerMap.put(HttpHeaders.CONTENT_TYPE, Arrays.asList(new Object [] { MediaType.APPLICATION_JSON }));

身体内容的一部分:

JsonObject value = Json.createObjectBuilder()
    .add("var1", var1Object)
    .add("var2", var2Object)
    .add("var3", var3Array)
    .add("var4", var4Array)
    .build();

post方法调用:

Response response = client
    .target("https://example.com")
    .request("application/json")
    .headers(headerMap)
    .post(Entity.text(value.toString()));

我得到的错误:

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at java.util.AbstractList.removeRange(Unknown Source)
at java.util.AbstractList.clear(Unknown Source)
at javax.ws.rs.core.AbstractMultivaluedMap.putSingle(AbstractMultivaluedMap.java:97)
at org.glassfish.jersey.message.internal.OutboundMessageContext.setMediaType(OutboundMessageContext.java:708)
at org.glassfish.jersey.client.ClientRequest.type(ClientRequest.java:419)
at org.glassfish.jersey.client.ClientRequest.variant(ClientRequest.java:443)
at org.glassfish.jersey.client.JerseyInvocation$Builder.storeEntity(JerseyInvocation.java:179)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:427)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:334)
at main.java.ofbizrestclientdemo.Main.testCreateProduct(Main.java:438)
at main.java.ofbizrestclientdemo.Main.main(Main.java:520)

我一直试图找到这个问题的原因一段时间,但无济于事。任何人都能看出是什么激发了这个错误?

提前致谢。

答案

问题是由headerMap中的这些值引起的:

headerMap.put("Authorization", Arrays.asList(new Object [] { authorizationHeaderValue }));
headerMap.put(HttpHeaders.CONTENT_TYPE, Arrays.asList(new Object [] { MediaType.APPLICATION_JSON }));

Arrays.asList返回一个不可修改的地图,但是AbstractMultivaluedMap.putSingle试图清除值列表,这是列表不允许的,并且抛出了UnsupportedOperationException

我建议用正常的Arrays.asList初始化(List)替换new ArrayList<>()

另一答案

更改

.POST(Entity.text(value.toString()));

.POST(Entity.json(value.toString()));

在你的客户电话中。 Entity.text生成“text / plain”内容类型。

Doc:https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/Entity.html#text-T-

以上是关于REST客户端Content-Type标头抛出UnsupportedOperationException的主要内容,如果未能解决你的问题,请参考以下文章

REST 错误-请求包含实体主体但没有 Content-Type 标头。推断的媒体类型 application/octet-stream 不支持此资源

Firefox 不支持 xhrPost 中的 Content-type 标头

调用 HTTPClient.PostAsync 时设置 Authorization/Content-Type 标头

如何将带有数据的http标头发送到rest Api codeigniter?

Jersey 客户端错误 - 无法解析无效的 Content-Type 标头(需要解决方法)

在 C# 中将 HTTP Accept 和 Content-Type 标头都设置为“application/xml”