Formatting HTTP Post Request Parameters with nested in JAVA android - java

I'm trying to post the following data to my rails App. It's expecting the format to be as follows:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"oSJ2ut0T1HGJ+KcBAPPP4lwn8Hc4Xwkn8emVujXy9xQ=",
"wine"=>{"name"=>"nice wine", "vintage"=>"1923", "price"=>"412.2", "photo"=>#<ActionDispatch::Http::UploadedFile:0x007f9c86243d38 #tempfile=#<Tempfile:/var/folders/z9/r6hjby6x2cvfrlldtv7djz8c0000gn/T/RackMultipart20140825-4734-em8b0l>, #original_filename="timtams.jpeg",
#content_type="image/jpeg",
#headers="Content-Disposition: form-data; name=\"wine[photo]\"; filename=\"timtams.jpeg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create Wine"}
However, I'm getting this now from my android app:
Parameters: {
"photo"=>#<ActionDispatch::Http::UploadedFile:0x007f8b69bd2968 #tempfile=#<Tempfile:/var/folders/z9/r6hjby6x2cvfrlldtv7djz8c0000gn/T/RackMultipart20140827-3309-f5b613>, #original_filename="20140608_172146-3-1.jpg", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"photo\"; filename=\"20140608_172146-3-1.jpg\"\r\nContent-Type: application/octet-stream\r\n">,
"name"=>"test1",
"vintage"=>"1927",
"price"=>"19.27"}
Is there a way to define "wine" in front of the parameters?
The following are my current codes:
/**
* Created by zhongqinng on 26/8/14.
*/
public class UploadAsync extends AsyncTask {
private String TAG = "UploadAsync";
#Override
protected Object doInBackground(Object[] params) {
postMyWine2();
return null;
}
public void postMyWine2(){
Log.i(TAG, "postMyWine2 start");
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(WineStoryHTTPClient.BASE_URL + "/wines");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
File photofile = new File("/storage/sdcard0/Download/20140608_172146-3-1.jpg");
builder.addPart("photo", new FileBody(photofile));
builder.addTextBody("name", "test1");
builder.addTextBody("vintage", "1927");
builder.addTextBody("price", "19.27");
post.setEntity(builder.build());
Log.i(TAG,"postMyWine2 post.getParams() = "+post.getParams());
try {
Log.i(TAG,"postMyWine2 posting");
HttpResponse response = client.execute(post);
} catch (Exception e) {
Log.i(TAG,"postMyWine2 post Exception");
e.printStackTrace();
}
// HttpEntity entity = response.getEntity();
}
}

Managed to solve the issue by implementing a workaround at server side:
changed the format which server side expects.
however i'm still interested to find out how to format the post params from client side.
def create
# #wine = Wine.new(wine_params)
#wine = Wine.new( :name => params[:name], :vintage => params[:vintage], :price => params[:price] ,:photo => params[:photo])
respond_to do |format|
if #wine.save
format.html { redirect_to #wine, notice: 'Wine was successfully created.' }
format.json { render :show, status: :created, location: #wine }
else
format.html { render :new }
format.json { render json: #wine.errors, status: :unprocessable_entity }
end
end
end

Related

Converting from DescribeSObjectResult to JsonArray (or to HttpEntity)

A couple of weeks ago, I asked a question about reading Salesforce data using the SOAP API instead of the REST API (see Trying to use Apache Gobblin to read Salesforce data using SOAP API(s) instead of REST API ), but unfortunately nobody answered it, and so I am trying to implement the solution (with a little help) directly.
Using the REST API, the existing code that reads in a table's definition (by making a call to the REST API) looks like this:
// the URL starts with the Salesforce REST API endpoint, and ends with "/describe"
public String getSchema(String url, String accessToken, HttpClient httpClient) {
String jsonStr;
HttpRequestBase httpRequest = new HttpGet(url);
if (accessToken != null) {
httpRequest.addHeader("Authorization", "OAuth " + this.accessToken);
}
httpRequest.addHeader("Content-Type", "application/json");
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpRequest);
StatusLine status = httpResponse.getStatusLine();
httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
jsonStr = EntityUtils.toString(httpEntity);
}
if (status.getStatusCode() >= 400) {
System.out.println("There was an error. Http Status code of " + status.getStatusCode());
EntityUtils.consumeEntity(httpEntity);
return null;
}
return jsonStr;
} catch (Exception e) {
e.printStackTrace();
return null;
}
return jsonStr;
}
I would like to write a method that uses the Salesforce SOAP API (using the generated "partner.wsdl" file) similar to the following incomplete code:
public String getSchemaViaSoap(String tableName) {
String jsonStr;
PartnerConnection partnerConnection = ...;
try {
DescribeSObjectResult[] dsrArray = partnerConnection.describeSObjects(new String[] { entity });
// Since we described only one sObject, we should have only
// one element in the DescribeSObjectResult array.
DescribeSObjectResult dsr = dsrArray[0];
String jsonStr = ...; /* this is where I need help in converting dsr into a similar JSON string. */
} catch (ConnectionException e) {
e.printStackTrace();
log.error("Error getting connection", e);
System.out.println("Error getting connection" + e);
return null;
}
return jsonStr;
}
Any sort of help in determining how to convert from the DescribeSObjectResult object to a similar JsonString / HttpEntity / StringEntity object would be greatly appreciated.
You have consumed the WSDL, right? The DescribeSObjectResult is a normal class in your project. So... my Java is rusty but seems the question is simple "how to convert a Java object to JSON"?
There are libraries for this, right? Jackson for example. This helps? Converting Java objects to JSON with Jackson
I'm not sure if you'll end with identical result but should be close enough.

How to return response from rest api when uploading media file in an Angular 8 app?

I'm using a file upload example from the following link:
enter link description here
You can see in the example that the server need to return status "progress"
in order to see the progress bar.
What I have in my rest api at the moment:
#POST
#Path("Trip/{tripId}")
#Consumes("multipart/form-data")
#Produces("application/json")
public Response uploadTripVideo(#PathParam("tripId") Integer tripId, MultipartFormDataInput input){
String fileName = "";
Map<String, InputPart> uploadForm = input.getFormData();
InputPart inputPart = uploadForm.get("uploadedFile");
try {
MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
//convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class,null);
byte [] bytes = IOUtils.toByteArray(inputStream);
//constructs upload file path
fileName = "C:\\Users\\name\\Documents\\myfolder\\trip\\"+ tripId + "\\video\\" + fileName;
writeFile(bytes,fileName);
} catch (IOException e) {
e.printStackTrace();
}
return Response.status(200)
.entity("uploadFile is called, Uploaded file name : " + fileName).build();
}
here is my service call:
uploadVideo(url: string, file: File): Observable<any> {
let formData = new FormData();
formData.append('uploadedFile', file, file.name);
return this.http.post<any>(this.baseUrl + url, formData, {
reportProgress: true,
observe: 'events'
}).pipe(
map(event => this.getEventMessage(event, formData)),
catchError(this.handleError)
);
}
Any idea how to return a response that should indicate on the progress? The probrem is that the event is not coming when calling the service, here is
the code where I subscribe to the post request:
this.upload.uploadVideo(url, this.videoToUpload)
.subscribe(
(event) => {
console.log(event);
if (event.type === HttpEventType.DownloadProgress) {
console.log("download progress");
}
if (event.type === HttpEventType.Response) {
console.log("donwload completed");
}
this.videoUpload = event;
//console.log("POST call successful value returned in body", val);
},
err => {
this.videoUploadError = err;
//console.log("POST call in error", response);
},
() => {
//console.log("The POST observable is now completed.");
});
What I'm getting is error in the console:
Backend returned code undefined, body was: undefined
UPDATE
I've removed the following code and things start moving:
//.pipe(
// map(event => this.getEventMessage(event, formData)),
// catchError(this.handleError)
// );
You can easily do this by setting the reportProgress flag to true in your POST HttpRequest.
The key here is to create a HttpRequest and pasing it to the HttpClient.request method rather than directly calling the post() method.
Once subscribed to the request, you need to check for the event type as
event.type == HttpEventType.UploadProgress
to perform the logic to show loading percentage as
100 * event.loaded / event.total
and check for the completion as
event.type === HttpEventType.Response
Demo at https://stackblitz.com/edit/angular-http-post-status

Vaadin Front-end and Token/Cookie

I'm using nodeJS in the back-end environment and most of APIs are ready. I want to use Vaading in the front-end, because of the Java Spreadsheet component. I have looked at the Bakery example and designed a login page which sends the user credentials to my back-end API. This is the code for sending the POST request to the server.
public void submit(String username, String password) throws IOException {
JSONObject json = new JSONObject();
json.put("username", username);
json.put("password", password);
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost request = new HttpPost(URL);
HttpResponse response;
StringEntity params = new StringEntity(json.toString());
request.addHeader("content-type", "application/json");
request.setEntity(params);
response = httpClient.execute(request);
if(response.getStatusLine().getStatusCode() == 200) {
System.out.println("Okey!");
// The response contains token. How can I store this token?
// Also, How can I use the stored token for future Authentication:Bearer?
}
}
catch(Exception ex) {
System.out.println(ex);
}
finally {
httpClient.close();
}
}
I would like to store the response's token in somewhere(I can store it in the cookie object in React. However, I'm not familiar with this language) and fetch the token from this storage(cookie possibly, how to implement Cookie in Java web?) every time I make a request.
Which version of Vaadin do you use? If you are using Vaadin >= 10: How about using the session?
You could save the token in the VaadinSession and read it from there on every request.
I created a minimum example where (on button click) I check if a token is already saved in the session. If yes it is printed in a notification. If not it is saved into the session. The code looks like:
#Route("")
public class MainView extends VerticalLayout {
public MainView() {
Button button = new Button("Click me", event -> {
Object token = VaadinSession.getCurrent().getAttribute("token");
if (token == null) {
Notification.show("No token found in session. Now storing token = 123456");
VaadinSession.getCurrent().setAttribute("token", "123456");
} else {
Notification.show("Found token in session: " + token.toString());
}
});
add(button);
}
}
The result looks like:
(button was clicked three times)
Update: The same can be used in Vaadin 8 where the code of a minimum example then looks like:
#Theme("mytheme")
public class MyUI extends UI {
#Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
Button button = new Button("Click me", event -> {
Object token = VaadinSession.getCurrent().getAttribute("token");
if (token == null) {
Notification.show("No token found in session. Now storing token = 123456");
VaadinSession.getCurrent().setAttribute("token", "123456");
} else {
Notification.show("Found token in session: " + token.toString());
}
});
layout.addComponents(button);
setContent(layout);
}
#WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}

How to pass array of variables to REST URL in android?

I have to make registration using REST URL. REST services are written in Java now i have to pass the set of parameters in that secGameIds parameter is like this [100,102]. Example registration using Insomnia:::
{
"firstName":"parent111",
"lastName":"sadfsdf",
"email":"abc#bbc.com",
"date":"2000-06-09",
"phoneNum":"8765654454",
"gender":"male",
**"secGameIds":[0,0],**
"roleId":102
}
How should i provide secGameIds parameter value is it a ArrayList or Array?
for remaining values i have created JSONObject class object and adding values to that object and 'm appending that object to url
{
JSONObject json = new JSONObject();
json.put("fistName","aaa");
..
..
HttpPost post = new HttpPost(uri);
post.setHeader("Content-type", "application/json");
post.setEntity(new StringEntity(json.toString(), "UTF-8"));
DefaultHttpClient client = new DefaultHttpClient();
httpresponse = client.execute(post);
}
where as for secGameId i have tried like below,
{
int[] secGameId = {100,102};
}
-- gives me an error in back-end like "nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of int[] out of VALUE_NUMBER_INT token"
I even tried by using
{
ArrayList<Integer> secGameId = new ArrayList<String>();
secGameId.add(100);
secGameId.add(102);
}
and passing to value...
{
json.put("secGameIds":secGameId)
}
again at server side i kicked with the same error.
Can anyone help me?
public static String httpPost(HashMap<String, String> map, String url,String token) {
Log.e("call ", "running");
HttpRequest request;
if(token!=null){
request = HttpRequest.post(url).accept("application/json")
.header("Authorization", "Token " + AppInfo.token).form(map);
}
else
request = HttpRequest.post(url).accept("application/json").form(map);
int responseCode = request.code();
String text = request.body();
Log.e("response", " "+responseCode+ " "+ text);
if(responseCode==400){
return "invalid_tocken";
}
else if(responseCode<200 || responseCode>=300) {
return "error";
}
return text;
}
Hope you can convert the JSONArray to HashMap. If you instead need to post it as a JSONArray itself, then OkHttp library will help you.

How to add headers to ZeroCopyPost

I am trying to upload an image file to a web storage server using zero copy post.
The implementation comes from the example in the Apache website. I've changed some parts from the example so that the response is not downloaded in a file.
Here's the source code that I have changed.
private void upload() throws Exception {
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
httpclient.start();
File upload = new File("C:\\Users\\Jee\\profile.png");
ZeroCopyPost httpost = new ZeroCopyPost(requestURL+upload.getName(), upload,
ContentType.create("image/png"));
HttpAsyncResponseConsumer consumer = new BasicAsyncResponseConsumer();
Future<File> future = httpclient.execute(httpost, consumer, null);
File result = future.get();
System.out.println("Response file length: " + result.length());
System.out.println("Shutting down");
} finally {
httpclient.close();
}
System.out.println("Done");
}
I need to add headers to this POST request. How is it done?
ZeroCopyPost zeroCopyPost = new ZeroCopyPost(
URI.create("/"),
new File("stuff"),
ContentType.DEFAULT_BINARY) {
#Override
protected HttpEntityEnclosingRequest createRequest(
final URI requestURI, final HttpEntity entity) {
HttpEntityEnclosingRequest request = super.createRequest(requestURI, entity);
request.setHeader("my-header", "whatever");
return request;
}
};
Overriding ZeroCopyPost#createRequest is the recommended way. Overriding #generateRequest per #Robert Rowntree recommendation would work as well.

Categories

Resources