Nelson Lopes
Nelson Lopes

Reputation: 137

REST client Content-Type header throws UnsupportedOperationException

I am developing a REST client to connect to an external server, which I do not have access to. I've been able to successfully stablish communication using Postman and SOAPUi, and now I'm trying with Java (org.glassfish.jersey.client.ClientResponse), but to no avail, because whenever I include "Content-type: application/json" header, I get an exception and if I do not include this header, I get an 415 error (Unsupported Media Type), which I believe is asking me to include the Content-Type header.

Here is the headers preparation:

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 }));

A part of what goes in the body:

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

The post method call:

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

And the error I get:

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)

I have been trying to find the cause for this problem for some time, but to no avail. Can anyone see what motivates this error?

Thanks in advance.

Upvotes: 2

Views: 3454

Answers (2)

Antot
Antot

Reputation: 3964

The problem is caused by these values in headerMap:

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

Arrays.asList returns an unmodifiable map, but AbstractMultivaluedMap.putSingle tries to clear the list of values, which is not allowed for the list and an UnsupportedOperationException is thrown.

I suggest replacing Arrays.asList with normal List initialization (new ArrayList<>()).

Upvotes: 3

The Guest
The Guest

Reputation: 708

Change

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

to

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

in your client call. Entity.text produces "text/plain" content type.

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

Upvotes: 1

Related Questions