Spring boot and Android Retrofit 2.0 , file upload with json data - java

I have a REST API written using Spring boot and i am trying to POST an image and json data through Android client/app where i am using retrofit 2.0 . While doing that , i can see the data appearing but image file is showing as NULL.
can you please help me how to do this or let me know where i am doing the mistake
Server side REST Controller :
#RequestMapping(value = "/v1/producttest", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public #ResponseBody ProductTestResponse create( #Valid String producttestEntry,
#RequestPart(value = "file", required = false) MultipartFile file) {
LOGGER.info("Creating a product test: {}", producttestEntry);
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map;
try {
map = mapper.readValue(productbuyerEntry, Map.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Android Side code:
MultipartBody.Part reqFile = MultipartBody.Part.createFormData("file", finalFile.getName(), RequestBody.create(okhttp3.MediaType.parse("multipart/form-data"), finalFile));
Call <PostTestresponse> cal = restInterface.Posttest(hj, reqFile);

Related

How to send java object as post parameter with server bean mapping

I am currently writing a client to access rest service, the server rest call accepts one parameter of type java object with #BeanParam annotated.
How do i send data from Apache HTTP client to achieve this.
Below is my server and client code
Server code
#Override
#POST
#Path("/generate_verify_otp/{issuername}")
#Produces("application/x-www-form-urlencoded")
#Consumes("application/x-www-form-urlencoded")
public MultivaluedMap<String, Object> generateVerifyOTP(#BeanParam QPayOTPRequest qpayOTPRequest, #PathParam("issuername")) {
some business logic
}
Client code
public void getOtp(HttpServletRequest request){
QPayOTPRequest qpayOTPRequest = formatDataForOtp(request);
StringWriter writer = new StringWriter();
JsonGenerator jgen;
try {
jgen = new JsonFactory().createJsonGenerator(writer);
jgen.setCodec(new ObjectMapper());
jgen.writeObject(qpayOTPRequest);
jgen.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(writer.toString());
String url = "sdfghjklfghjk;
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try {
HttpPost post = new HttpPost(url);
StringEntity entiry = new StringEntity(writer.toString());
post.addHeader("content-type", "application/x-www-form-urlencoded");
post.setEntity(entiry);
HttpResponse response = httpClient.execute(post);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
How to i send parameters from client so that it maps to #beanparam object.

Performance tune code in O (n^2) to be more performant

I have this spring boot java controller having code that utilizes the OpenKM document management API to search the document management system for documents and display results using Ajax, HTML, CSS and Jquery datatables on the front-end.
Due to the way the API was written, I cannot get a document object with its metadata in one call but will need to use an output of the first API operation's call as a filter for another API operation method in two nested for loops.
Additionally, I had to iterate the toString method of an API return object to retrieve the metadata information, as they were not accessible through the return object's properties.
The problem is the performance of this code. I would like to see if there is a way to optimize this code.
// Read the property or metadata to use in constituting the StoredDocument object
for (QueryResult queryResult : resultSet.getResults()) {
// Create a locally-scoped List<String>
List<String> listOfStoredDocumentProperties = new ArrayList<String>();
Document document = queryResult.getDocument();
String nodeId = document.getPath();
// Populate storedDocument object
storedDocument = new StoredDocument();
storedDocument.setAuthor(document.getAuthor());
storedDocument.setCreated(document.getCreated());
storedDocument.setLastModified(document.getLastModified());
storedDocument.setPath(document.getPath());
storedDocument.setPermissions(document.getPermissions());
storedDocument.setSize(document.getActualVersion().getSize());
storedDocument.setUuid(document.getUuid());
storedDocument.setVersionNumber(document.getActualVersion().getName());
// System.out.println(nodeId);
try {
listOfFormElement = okm.getPropertyGroupProperties(nodeId, documentVo.getGroupId());
int counterForTrackingDocDirectionPos = 0;
for (FormElement formElement : listOfFormElement) {
++counterForTrackingDocDirectionPos;
if (counterForTrackingDocDirectionPos == 4) {
String formElementString = formElement.toString();
// System.out.println("formElementString: " + formElementString);
System.out.println("name: " + formElement.getName());
System.out.println("formElement: " + formElement);
String transformedFormElementString = StringUtils.EMPTY;
try {
transformedFormElementString = formElementString.substring(0, formElementString.indexOf(", selected=true"));
// Read the string from a position that is 3 steps before the last position in the string.
transformedFormElementString = transformedFormElementString
.substring(transformedFormElementString.length() - 3, transformedFormElementString.length()).trim();
transformedFormElementString = transformedFormElementString.startsWith("=")
? transformedFormElementString.substring(1, transformedFormElementString.length()) : transformedFormElementString;
} catch (Exception ex) {
// To catch scenario where formElementString.indexOf(", selected=true") does not find the
// specified string. This happens when document direction is not set and therefore is
// selected=false for both the options IN and OUT.
transformedFormElementString = "NOT SET";
}
listOfStoredDocumentProperties.add(transformedFormElementString);
System.out.println("transformedFormElementString: " + transformedFormElementString);
} else {
String formElementString = formElement.toString();
String transformedFormElementString = formElementString.substring(formElementString.indexOf("value="),
formElementString.indexOf("data="));
// Remove the preceding 'value=' and the last 2 character-constituted string ", "
transformedFormElementString = transformedFormElementString.substring(6, transformedFormElementString.length() - 2).trim();
listOfStoredDocumentProperties.add(transformedFormElementString);
}
}
storedDocument.setCompanyName(listOfStoredDocumentProperties.get(0));
storedDocument.setProductLine(listOfStoredDocumentProperties.get(1));
storedDocument.setSubjectHeading(listOfStoredDocumentProperties.get(2));
storedDocument.setDocumentDirection(listOfStoredDocumentProperties.get(3));
storedDocument.setDocumentType(listOfStoredDocumentProperties.get(4));
storedDocument.setReferenceNumber(listOfStoredDocumentProperties.get(5));
storedDocument.setDate(ISO8601.parseBasic(listOfStoredDocumentProperties.get(6)).getTime().toString());
// Add the storedDocument object to the return list
listOfstoredDocuments.add(storedDocument);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchGroupException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PathNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DatabaseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WebserviceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The solution for it is extending the REST API. In the professional edition, the REST API is extensible with plugins architecture https://docs.openkm.com/kcenter/view/okm-6.4/creating-your-own-rest-plugin-(-extending-rest-api-).html, in the community this option still is not present. The idea is to build a method from server side what provide the exact data what really you need, creating high-level methods.

Java : How can convert String to HttpInputMessage

How can I convert String to HttpInputMessage?
or HttpResponse to HttpInputMessage
Post (return json):
HttpResponse<String> jsonResponse = null;
try {
jsonResponse = Unirest.post(targetURL).header("Accept", "application/json")
.header("Content-Type", "application/json;").body(urlParameters).asString();
} catch (UnirestException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String str = jsonResponse.toString();
HttpInputMessage inputMessage = null;
return inputMessage;
I want convert json to Object
RoutesList routes = new RoutesList();
Post post = new Post(this.url + allRoutes, depoId.toString());
HttpInputMessage inputMessage = null;
try {
inputMessage = post.getResult();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
converter.read(routes.getClass(), RoutesList.class, inputMessage);
} catch (HttpMessageNotReadableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can wrap the HttpResponse using this class HttpComponentsAsyncClientHttpResponse:
HttpComponentsAsyncClientHttpResponse(HttpResponse httpResponse)
And return it as HttpInputMessag, for example:
return new HttpComponentsAsyncClientHttpResponse(jsonResponse)
this class implement the interface HttpInputMessage.

How to return a JSON Array from java server to ios app

I has an ios app which sends a http request to a REST service I have running on a local server. The server gets some information from the Twitter api and then sends it back to the ios app. I have put the data I want to send back in a JSONArray. How do I go about sending this array back as a response to the request.
I have included the method that receives the request and which initially sent back a string. I would like to change so it sends back the "returnedArray" array instead.
#Path("/hello")
public class HelloResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() throws JSONException {
String convert = null;
JSONArray returnedArray = new JSONArray();
try {
returnedArray = TweetUsingTwitter4jExample.getTweets();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return convert;
}
}
Call toString() on the JSONArray.

JSON io writer delete JSONObject on Android

I'm currently using the library JSON-io. I created a desktop application which when a person want to log in in the system send an JSONObject with his username and password. Then the server send back the response if the person is allowed or not (also a JSONObject). Until here everything works fine.
Now i want to make an Android app. I take the same code than before for login but the application crashes.
The code for login is launch from an AsyncTask and i put the permission to access to Internet to the Manifest.
I perform some testing and it occurs that the method write of JSONWriter "delete" my JSON because on the server side he receives this : {}. I tried to hardcode the JSONObject on the server side (the server's code works fine because we can use the desktop app) but this time the readObject on the android App receives also {}.
We tried to send jsonObject.toString() and this time it worked (except that the server isn't configured to handle a string).
Do anyone knows why on android the two methods write and readObject are deleting the JSON ?
Thank you.
EDIT:
Here the code i wrote:
On the android App
protected Boolean doInBackground(Void... params) {
// 3 : create a JSON object and send it to server for verification
JSONObject loginJS = new JSONObject();
try {
loginJS.put("type", Type.LOGIN); // Type is an enum
loginJS.put("username", userName);
loginJS.put("hash", mPassword);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user = new User();
System.out
.println("User created and ready to connect to the spu for login");
user.connexionToSPU(); // This method works
System.out.println("LoginJS = "+loginJS.toString()); At this point the print of the JSON is fine we have {"type":"Login", ....}
user.sendToSPU(loginJS); //This is where there's a problem
// 4 : wait response
JSONObject loginResponseJS = user.receiveFromSPU(); // And when i hard code the JSON on the server side receiveFromSPU get a empty JSON
Method connexionToSPU:
public void connexionToSPU() {
jswSPU = null;
jsrSPU = null;
Socket socket = null;
try {
socket = new Socket(prop.readPropertiesXML("IP_adress_server"),
Integer.parseInt(prop.readPropertiesXML("port_server")));
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
jswSPU = new JsonWriter(socket.getOutputStream());
jsrSPU = new JsonReader(new BufferedInputStream(socket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sendToSPU method
public void sendToSPU(JSONObject json) {
try {
jswSPU.write(json);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ReceiveFromSPU method
public JSONObject receiveFromSPU() {
JSONObject json = null;
try {
json = (JSONObject) jsrSPU.readObject();
System.out.println("JSON FROM THE SERVER : "+json.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return json;
}
Hope it will be sufficiently clear.
Thank you

Categories