Using the Jersey client to do a POST operation - java

In a Java method, I'd like to use a Jersey client object to do a POST operation on a RESTful web service (also written using Jersey) but am not sure how to use the client to send the values that will be used as FormParam's on the server. I'm able to send query params just fine.

Not done this yet myself, but a quick bit of Google-Fu reveals a tech tip on blogs.oracle.com with examples of exactly what you ask for.
Example taken from the blog post:
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("name1", "val1");
formData.add("name2", "val2");
ClientResponse response = webResource
.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.post(ClientResponse.class, formData);
That any help?

Starting from Jersey 2.x, the MultivaluedMapImpl class is replaced by MultivaluedHashMap. You can use it to add form data and send it to the server:
WebTarget webTarget = client.target("http://www.example.com/some/resource");
MultivaluedMap<String, String> formData = new MultivaluedHashMap<String, String>();
formData.add("key1", "value1");
formData.add("key2", "value2");
Response response = webTarget.request().post(Entity.form(formData));
Note that the form entity is sent in the format of "application/x-www-form-urlencoded".

It is now the first example in the Jersey Client documentation
Example 5.1. POST request with form parameters
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9998").path("resource");
Form form = new Form();
form.param("x", "foo");
form.param("y", "bar");
MyJAXBBean bean =
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE),
MyJAXBBean.class);

If you need to do a file upload, you'll need to use MediaType.MULTIPART_FORM_DATA_TYPE.
Looks like MultivaluedMap cannot be used with that so here's a solution with FormDataMultiPart.
InputStream stream = getClass().getClassLoader().getResourceAsStream(fileNameToUpload);
FormDataMultiPart part = new FormDataMultiPart();
part.field("String_key", "String_value");
part.field("fileToUpload", stream, MediaType.TEXT_PLAIN_TYPE);
String response = WebResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).post(String.class, part);

Simplest:
Form form = new Form();
form.add("id", "1");
form.add("name", "supercobra");
ClientResponse response = webResource
.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.post(ClientResponse.class, form);

Also you can try this:
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("name1", "val1");
formData.add("name2", "val2");
webResource.path("yourJerseysPathPost").queryParams(formData).post();

Related

How change state Openhab item using Jersey?

How change state Openhab item using Jersey?
Source-code:
ClientConfig clientConfig = new ClientConfig();
Client client = ClientBuilder.newClient(clientConfig);
WebTarget webTarget = client.target("http://demo.openhab.org:8080/rest");
WebTarget resourceWebTarget = webTarget.path("things");
Form form =new Form();
if (item.getState().equals("ON"))
form.param("state", "OFF");
else
form.param("state", "ON");
response =
webTarget.path("items").path("Light_GF_Corridor_Ceiling").request()
.header("Content-Type", "text/plain")
.header("Accept", "application/json")
.post(Entity.entity(form,MediaType.APPLICATION_JSON),Response.class);
System.out.println("Status Info Response " + response.getStatusInfo());
Output:
Status Info Response Unsupported Media Type
Form is not meant to be used with application/json (it's meant to be used with application/x-www-form-urlencoded). With JSON, you are either supposed to used POJOs, collections of POJOS, or Strings. If you want to send collections of POJOs, you need to wrap it in GenericEntity.

Sending POST request with body in netty

I want to do POST request to some API by netty. Request must contains parameters as form-data in body. How I try to do this:
FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, POST, url);
httpRequest.setUri("https://url.com/myurl");
ByteBuf byteBuf = Unpooled.copiedBuffer(myParameters, Charset.defaultCharset());
httpRequest.headers().set(ACCEPT_ENCODING, GZIP);
httpRequest.headers().set(CONTENT_TYPE, "application/json");
httpRequest.headers().set(CONTENT_LENGTH, byteBuf.readableBytes());
httpRequest.content().clear().writeBytes(byteBuf);
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CNXN_TIMEOUT_MS)
.handler(new ChannelInitializerCustomImpl());
ChannelFuture cf = b.connect(url.getHost(), port);
cf.addListener(new ChannelFutureListenerCustomImpl();
That's worked ok, but result is different from I received by postman or other instruments.
What's the correct way to set my parameters as form-data to request body?
I solved this problem by using Apache httpcomponents library to create HtppEntity, serialize it to byte array and set to netty ByteBuf and also use jackson for parse json from String to Map:
Map<String, String> jsonMapParams = objectMapper.readValue(jsonStringParams, new TypeReference<Map<String, String>>() {});
List<NameValuePair> formParams = jsonMapParams.entrySet().stream()
.map(e -> new BasicNameValuePair(e.getKey(), e.getValue()))
.collect(Collectors.toList());
HttpEntity httpEntity = new UrlEncodedFormEntity(formParams);
ByteBuf byteBuf = Unpooled.copiedBuffer(EntityUtils.toByteArray(httpEntity));
httpRequest.headers().set(ACCEPT_ENCODING, GZIP);
httpRequest.headers().set(CONTENT_TYPE, "application/x-www-form-urlencoded");
httpRequest.headers().set(CONTENT_LENGTH, byteBuf.readableBytes());
httpRequest.content().clear().writeBytes(byteBuf);
I think that your request header is not set correct, to set content_type to "application/x-www-form-urlencoded" and have a try.

Dropwizard Jersey client Multipart http request

Dropwizard (Version 0.8.2) uses Jersey internally to provide HTTP client. I am using this client to send a Multipart POST request to an external Rest Endpoint to a SMS Service. Code is given below but it doesn't seems to be working because i am not receiving any message through this method also it does not throw any error.
URI for the first sample is http://enterprise.com/GatewayAPI/rest?userid=%s&password=%s&method=xlsUpload&filetype=zip&msg_type=TEXT&auth_scheme=PLAIN&v=1.1
FileDataBodyPart fileDataBodyPart = new FileDataBodyPart(fileName, file,
MediaType.APPLICATION_OCTET_STREAM_TYPE);
FormDataMultiPart multiPart = new FormDataMultiPart();
multiPart.field("fileName", fileName).bodyPart(fileDataBodyPart);
Entity<FormDataMultiPart> entity =
Entity.entity(multiPart, multiPart.getMediaType());// MediaType.MULTIPART_FORM_DATA_TYPE)
Client tenacityClient = TenacityJerseyClientBuilder
.builder(AppDependencyKeys.BULK_SMS)
.usingTimeoutPadding(Duration.milliseconds(500)).build(client)
.register(MultiPartFeature.class);
Invocation invocation = getResourceBuilder(tenacityClient, uri).buildPost(entity);
Future<Response> futureResponse = invocation.submit();
long start = System.currentTimeMillis();
futureResponse.get();
But the same works with below method when i use Apache Commons Httpclient. working code for the same is given below.
HttpClient client = new HttpClient();
PostMethod method = new
PostMethod("http://enterprise.com/GatewayAPI/rest");
Part[] parts = {
new StringPart("method", "xlsUpload"),
new StringPart("userid", "*******"),
new StringPart("password", "*******"),
new StringPart("filetype", "zip"),
new StringPart("v", "1.1"),
new StringPart("auth_scheme", "PLAIN"),
new FilePart(file.getName(), file)
};
method.setRequestEntity(new MultipartRequestEntity(parts, method.getParams()));
int statusCode = client.executeMethod(method);
log.info("Status code: {}", statusCode);
But i want to use the first way as that suits my infrastructure better.
I think you should set up properly media type for entity. Currently, you created new FormDataMultiPart but, you did not set and media type and it uses "text/plain" y default.
So, you should set up MediaType.APPLICATION_OCTET_STREAM_TYPE to your FormDataMultiPart as media type.

PHP RESTful API accessing Jersey Client POST data

I am using a PHP RESTful API which is consumed by a Java desktop application using jersey 2.21.
Usually, when I send a POST request from AngularJS, I can access the data via:
$data = json_decode(file_get_contents("php://input"));
However, when I use jersey, the data is put in the $_POST array. Here is my Jersey code:
final HashMap<String, String> params = // some hashmap with a few entries
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
MultivaluedMap formData = new MultivaluedHashMap(params);
WebTarget target = client.target(url);
// Get JSON
String jsonResponse = target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(formData, MediaType.APPLICATION_FORM_URLENCODED_TYPE), String.class);
return jsonResponse;
How do I post the data from Jersey so that I can access it via the above PHP call?
I know I can just use the $_POST array, but I need this API to be consumed from a mobile app, Java desktop & an AngularJS app.
Thanks in advance
Thanks to #jonstirling, I got it.
I had to set the content type as JSON. here is the updated code:
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target(url);
String data = new Gson().toJson(params);
// POST JSON
Entity json = Entity.entity(data, MediaType.APPLICATION_JSON_TYPE);
Invocation.Builder builder = target.request(MediaType.APPLICATION_JSON_TYPE);
String jsonResponse = builder.post(json, String.class);
return jsonResponse;

How to POST JSON with Jersey WebResource.Builder?

I wanna POST a JSONOject or a Map using a Jersey Client with a WebSresource.Builder.
WebResource.Builder builder = res.type(mediaType);
uploadResult = builder.post(ClientResponse.class, new HashMap<String, Object>());
How do I pass the JSON the right way to the POSt request? How the JSON/Map has to be converted?
//cheers

Categories

Resources