I have a webservice that receibes a files with multipart (In c#), when i send a big file(15MB) by a chrome extension(Advanced Rest extension) the file uploads ok and i can see the body response:
<response xmlns="http://schemas.datacontract.org" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Descripcion>blabla</Descripcion>
<Resultado>-9999</Resultado>
<Servicio xmlns:a="http://schemas.datacontract.org" i:nil="true" />
</reponse>
But when i call with android i get the headers with an 200 code OK response but i dont know how can i get the body response:
This is my code:
/****** Informacion exif *****/
DefaultHttpClient mHttpClient;
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
mHttpClient = new DefaultHttpClient(params);
HttpPost httppost = new HttpPost("HTTPS://SERVICIO.SVC");
httppost.setHeader("Connection", "Keep-Alive");
httppost.setHeader("SOAPAction", "http://tempuri.org/Service1");
httppost.setHeader("identificadorGUID", Guid);
httppost.setHeader("numeroServicio", codigoServicio);
httppost.setHeader("coordenadaLatitud", latitud);
httppost.setHeader("coordenadaLongitud", longitud);
if (QUEES == 0) {
extension = "jpg";
}
if (QUEES == 1) {
extension = "mp4";
}
httppost.setHeader("cuando", cuando);
httppost.setHeader("tipoMultimedia", String.valueOf(tipoMultimedia));
httppost.setHeader("extension", extension);
MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fileBody = new FileBody(fichero, "multipart/form-data");
multipartEntity.addPart("image", fileBody);
httppost.setEntity(multipartEntity);
try {
HttpResponse response = mHttpClient.execute(httppost);
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
resEntity.consumeContent();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String sResponse;
StringBuilder s = new StringBuilder();
httppost.getAllHeaders();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.i("Respuesta web service", sResponse);
}
catch (ClientProtocolException e1) {
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
Crash with: java.io.IOException: Attempted read from closed stream.
How can i get the response to parse it?
Thanks
Looks like you shouldn't be calling consumeContent() until the information is read (given that it closes the stream). If you're using 4.1 or later, this method has been deprecated, and you should be using EntityUtils.consume(HttpEntity)
From its javadoc:
This method is called to indicate that the content of this entity is no longer required. All entity implementations are expected to release all allocated resources as a result of this method invocation. Content streaming entities are also expected to dispose of the remaining content, if any. Wrapping entities should delegate this call to the wrapped entity.
Related
I am uploading a File from GWT to a different domain
File Uploads well , But the response i sent from the server always reaches as "null" at the client side
response.setContentType("text/html");
response.setHeader("Access-Control-Allow-Origin", "*");
response.getWriter().print("TEST");
response is NULL only when i upload the file on a different domain ... (on same domain all is OK)
I also see this in GWT documentation
Tip:
The result html can be null as a result of submitting a form to a different domain.
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/FormPanel.SubmitCompleteEvent.html
Is there any way I can receive back a response at my client side when i am uploading file to a different domain
There are 2 possible answer:
Use JSONP Builder
JsonpRequestBuilder requestBuilder = new JsonpRequestBuilder();
requestBuilder.requestObject(url, new AsyncCallback<FbUser>() {
#Override
public void onFailure(Throwable ex) {
throw SOMETHING_EXCEPTION(ex);
}
#Override
public void onSuccess(ResponseModel resp) {
if (resp.isError()) {
// on response error on something
log.error(resp.getError().getMessage())
log.error(resp.getError().getCode())
}
log.info(resp.getAnyData())
}
Not to use GWT to upload, rather use other client like apache HttpClient
public uploadFile() {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
FileBody bin = new FileBody(new File(UPLOADED_FILE));
long size = bin.getContentLength();
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("PART", bin);
String content = "-";
try {
httpPost.setEntity(reqEntity);
HttpResponse response = httpClient.execute(httpPost, localContext);
HttpEntity ent = response.getEntity();
InputStream st = ent.getContent();
StringWriter writer = new StringWriter();
IOUtils.copy(st, writer);
content = writer.toString();
} catch (IOException e) {
return "false";
}
return content;
}
Hope it helps
#GET
#Path("/{loginId}")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadExportedFile(#PathParam("loginId") String loginId) {
File file = new File("D://abc.txt");
Response.ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename=newfile.txt");
response.type(MediaType.APPLICATION_OCTET_STREAM_TYPE);
return response.build();
}
This gives response as a content of file and not downloading it
Monika if you use spring I recommend return response entity resource with headers something like this
#GetMapping("/api/config)
fun config(#PathVariable id: String): ResponseEntity<Resource> {
val config = someService.getConfig(hotelId = id)
val resource InputStreamResource(objectMapper.writeValueAsString(config)
.byteInputStream(Charsets.UTF_8))
val responseHeaders = HttpHeaders()
responseHeaders.add("content-disposition",
"attachment;filename=config.json")
responseHeaders.add("Content-Type",MediaType.APPLICATION_OCTET_STREAM_VALUE)
return ResponseEntity.ok()
.headers(responseHeaders)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource)
}
Here you have some other answer about
Content-Disposition and Content Type
The frontend should not have an impact on downloading file.
Your code here is the API you are implementing and it returns the content of the file. Downloading your file should be done from a client by generating a new file after you get the content. For instance, with the HttpClient lib, you will get this code:
CloseableHttpClient client;
HttpGet request;
HttpResponse response;
HttpEntity entity;
try {
client = HttpClientBuilder.create().build();
request = new HttpGet(URI);
response = client.execute(request);
entity = response.getEntity();
// The file not found, or is not available
if(response.getStatusLine().getStatusCode() == 404) {
throw new CustomException("The URI is not valid");
} else {
InputStream is = entity.getContent();
try (FileOutputStream fos = new FileOutputStream(new File(newFilePath))) {
int inByte;
while((inByte = is.read()) != -1) {
fos.write(inByte);
}
}
is.close();
client.close();
}
} catch(IOException e) {
e.printStackTrace();
}
If you want the file to be directly downloaded when you call the URL, you have to give the complete path with the name of the file : http://yourhost/yourfile.txt, and of course the file should be available on the server. Behind this URL, it is just a href HTML tag, that will point on your file. In your API, your URL will looks something like this : #Path("/{loginId}/{file}"), where {file} stands for the file you want to download.
Here is the code I have so far.
What does works is reading all form name/values from the original request.
What does not work is the new server does not receive any of the newly assigned form name/values. Basically they dont seem to get transmitted to the secondary server.
There might be an easier way to do so?? All I need is to trigger on a specific form field from the new server and redirect to a sub-server that will handle the request and pass back the results thru the main server to the client (proxying).
String value = String.format("https://%s.myotherserver.com%s", "sub1", request.getRequestURI());
HttpPost uploadFile = new HttpPost(value);
uploadFile.addHeader("Content-Type", request.getContentType());
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
ContentBody cbFile = new InputStreamBody(request.getPart("audio").getInputStream(), ContentType.create("audio/webm"),"audio.ogg");
builder.addPart("audio", cbFile);
builder.addPart("text", new StringBody(request.getParameter("text"),ContentType.DEFAULT_TEXT));
builder.addPart("email", new StringBody(request.getParameter("email"),ContentType.DEFAULT_TEXT));
// now add the other original form name/values to new request
do
{
String parameterName = reqParameterNames.nextElement().toString();
Object parameterValue = request.getParameter(parameterName);
if (!privateParameters.contains("p_"+parameterName)) {
builder.addPart(new FormBodyPart(parameterName, new StringBody((String) parameterValue,ContentType.DEFAULT_TEXT)));
}
} while (reqParameterNames.hasMoreElements());
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
CloseableHttpClient httpClient2 = HttpClients.createDefault();
CloseableHttpResponse statusCode = httpClient2.execute(uploadFile);
HttpEntity responseEntity = statusCode.getEntity();
StringBuffer responseBuffer = new StringBuffer();
OutputStream output = response.getOutputStream();
ByteStreams.copy(responseEntity.getContent(), output);
output.flush();
I finally managed to get it to work with the following code. I hope this can help someone else;
MultipartEntityBuilder mb = null;
org.apache.http.HttpEntity entity =null;
String value = String.format("https://%s.myotherserver.com%s", "sub1", request.getRequestURI());
mb = MultipartEntityBuilder.create();
mb.addTextBody("noproxy", "true");
mb.addTextBody("text", request.getParameter("text"));
mb.addTextBody("email", request.getParameter("email"));
mb.addBinaryBody("audio", new File(inputAudioFilename));
entity = mb.build();
URLConnection conn = new URL(urlStr[i]).openConnection();
conn.setDoOutput(true);
conn.addRequestProperty(entity.getContentType().getName(), entity.getContentType().getValue());
conn.addRequestProperty("Content-Length", String.valueOf(entity.getContentLength()));
OutputStream fout = conn.getOutputStream();
entity.writeTo(fout);//write multi part data...
fout.flush();
fout.close();
OutputStream output = response.getOutputStream();
output.flush();
ByteStreams.copy(conn.getInputStream(),response.getOutputStream());
conn.getInputStream().close();
Scenario : Pass username and password in a json object to restful webservice and get a json object in return. Yeah, I know, Its simple but I can't get it work.
I have been trying to this from several days. So far, I have tried this:
My restful webservice code
#POST
#Path("/testJson")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject testJson(JSONObject inputJsonObj) throws Exception {
JSONObject myjson = new JSONObject();
if(inputJsonObj != null){
System.out.println("=================================");
System.out.println("JSON object = " + inputJsonObj.toString());
System.out.println("=================================");
}
else{
System.out.println("JSON is NULL");
}
myjson.put("success", "1");
System.out.println(myjson.toString());
// return "string returned";
return myjson;
}
And inside my android acivity, the code is
// POST request to <service>/SaveVehicle
HttpPost request = new HttpPost(myURL);
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
request.setHeader("user-agent", "Yoda");
try {
// Build JSON string
// JSONStringer vehicle = new JSONStringer().object()
// .key("getItInputTO").object().key("zipCode").value("90505")
// .key("financingOption").value("B").key("make")
// .value("Scion").key("baseAmountFinanced").value("12000")
// .key("modelYear").value("2010").key("trimCode")
// .value("6221").key("totalMSRP").value("15000")
// .key("aprRate").value("").endObject().endObject();
JSONObject myjson = new JSONObject();
myjson.put("1", "first");
myjson.put("2", "second");
StringEntity entity = new StringEntity(myjson.toString());
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json; charset=utf-8"));
request.setEntity(entity);
// Send request to WCF service
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
// HttpResponse response = httpClient.execute(request, localContext);
HttpResponse response = httpClient.execute(request);
resCode = response.getStatusLine().getStatusCode();
Toast.makeText(getApplicationContext(),
response.getStatusLine().getStatusCode() + "",
Toast.LENGTH_LONG).show();
if (resCode == 200) {
Toast.makeText(getApplicationContext(),
response.getStatusLine().getStatusCode() + "",
Toast.LENGTH_LONG).show();
HttpEntity entity2 = (HttpEntity) response.getEntity().getContent();
String text = getASCIIContentFromEntity(entity);
if(text!=null){
JSONObject obj = new JSONObject(text);
lblMsg.setText("Successful!");
}
// BufferedReader in = new BufferedReader(new
// InputStreamReader(response.getEntity().getContent()));
//
//
// String line = "";
// StringBuffer returnFromServer = new StringBuffer();
//
// while ((line = in.readLine()) != null) {
// returnFromServer.append(line);
// }
// // Toast what we got from server
// Toast.makeText(getApplicationContext(),
// returnFromServer.toString(), Toast.LENGTH_LONG).show();
//
// if (entity != null) {
// entity.consumeContent();
// }
}
} catch (Exception e) {
// TODO: handle exception
}
The commented sections show previous tries.
Output that I get on server console
=================================
JSON object = {}
=================================
{"success":"1"}
My server side receiver json object is not getting populated i don't know why.
Note:
I have INTERNET and many other permissions in my android manifest.
My webservice is up and running.
I have all the required jars i.e. jersey, json etc
I am using Tomcat 7 for restful webservice
I would highly appreciate any help.
Thanks
I have the same problem as yours.
I don't know why, but the temporary solution i am using is creating a class to handle those parameters.
That means using Jackson to convert Json Object <=> "Your Class"
See this tutorial for more information:
http://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/
===================================
And I just found this topic, it may be more useful than the upper solution:
Jersey POST Method is receiving null values as parameters
I'm working in a E-Commerce website, with JSF 2.
In order to communicate with the company that makes all the operation with the banks, I need to send this XML to them (it's just a sample provided from them):
<?xml version="1.0" encoding="ISO-8859-1"?>
<requisicao-transacao versao="1.2.0" id="6560a94c-663b-4aec-9a45-e45f278e00b4" xmlns="http://ecommerce.cbmp.com.br">
<dados-ec>
<numero>1001734898</numero>
<chave>e84827130b9837473681c2787007da5914d6359947015a5cdb2b8843db0fa832</chave>
</dados-ec>
<dados-pedido>
<numero>1603662828</numero>
<valor>100</valor>
<moeda>986</moeda>
<data-hora>2010-07-14T15:50:11</data-hora>
<idioma>PT</idioma>
</dados-pedido>
<forma-pagamento>
<bandeira>visa</bandeira>
<produto>A</produto>
<parcelas>1</parcelas>
</forma-pagamento>
<url-retorno>https://www.dummyurl.du/dummypage.do?id=trhjgnerifvnidjfnvmd</url-retorno>
<autorizar>1</autorizar>
<capturar>true</capturar>
</requisicao-transacao>
So after reading a lot about how to send and XML and receive it, I create this method:
public String rent(){
//String folderAndFile = createTransaction();
//creating the HTTP Post
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://qasecommerce.cielo.com.br/servicos/ecommwsec.do");
try {
//Reading the file as an entity
FileEntity entity = new FileEntity(new File("/home/valter.silva/sample.xml"));
entity.setContentType("text/xml");
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
System.out.println(EntityUtils.toString(httpEntity));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
But the output is always :
INFO: <?xml version="1.0" encoding="ISO-8859-1"?> <erro xmlns="http://ecommerce.cbmp.com.br"> <codigo>001</codigo> <mensagem>Requisição inválida</mensagem> </erro>
Which means that my .xml that I'm sending is invalid. That for some reason, the XML is wrong.. but what ?
Is alright the way that I'm sending the file ? What can I do about it ?
update
I was trying another approach but still the output is always the same, ..., is something wrong with my code ?
//approach v1
public String rent(){
//String folderAndFile = createTransaction();
try {
File file = new File("/home/valter.silva/test.xml");
HttpPost post = new HttpPost("https://qasecommerce.cielo.com.br/servicos/ecommwsec.do");
post.setEntity(new InputStreamEntity(new FileInputStream(file),file.length()));
post.setHeader("Content-type", "text/xml; charset=ISO-8859-1");
//creating the HTTP Post
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
System.out.println(EntityUtils.toString(httpEntity));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//approach v2
public String rent(){
//String folderAndFile = createTransaction();
try {
File file = new File("/home/valter.silva/test.xml");
HttpPost post = new HttpPost("https://qasecommerce.cielo.com.br/servicos/ecommwsec.do");
//creating the HTTP Post
DefaultHttpClient client = new DefaultHttpClient();
String fileInString = fileToString("/home/valter.silva/test.xml");
InputStream inputStream=new ByteArrayInputStream(fileInString.getBytes());//init your own inputstream
InputStreamEntity inputStreamEntity=new InputStreamEntity(inputStream,fileInString.length());
post.setEntity(inputStreamEntity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
System.out.println(EntityUtils.toString(httpEntity));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Can you check that the url where you trying to post can handle your xml correctly ?
I have tried to upload the xml you provided using just simple http post to the specified url and got
<?xml version="1.0" encoding="ISO-8859-1"?> <erro xmlns="http://ecommerce.cbmp.com.br"> <codigo>001</codigo> <mensagem>Requisição inválida</mensagem> </erro>
I prefer you first try to upload the xml from outside and then try with your code .
For example i used RESTClient of Mozilla addon .