PHP RESTful API accessing Jersey Client POST data - java

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;

Related

Apidaze REST API HTTP POST Call in Android/Java

I am trying to send SMS messages when a button is clicked in an Android app. I have the SMS sending code in Python using a REST API. The template looks like so:
import requests
url = "https://api.apidaze.io/{{api_key}}/sms/send"
querystring = {"api_secret":"{{api_secret}}"}
payload = "from=15558675309&to=15551234567&body=Have%20a%20great%20day."
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.request("POST", url, data=payload, headers=headers,
params=querystring)
print(response.text)
Because I am making an Android app, I need this to be in Java, but I am having trouble making the same POST request with the same parameters, headers, and body in JAVA.
Does anyone know how to make convert this template into something I can use for an Android app in Java?
There is a port of Apache Http Client for Android:
http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
Check the documentation, a simple POST request is very easy using this library:
HttpPost httpPost = new HttpPost("https://api.apidaze.io/" + api_key + "/sms/send");
String json = "{"api_secret":" + api_secret + "}";
StringEntity entity = new StringEntity(json);
httpPost.setEntity(entity);
httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
CloseableHttpResponse response = client.execute(httpPost);

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.

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.

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

Using the Jersey client to do a POST operation

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

Categories

Resources