I am writing an application which will send XML over HTTP to a server, and receive XML as the response. I am able to send XML to the server but not able to receive the response.
This is my client code:
public void sendXMLToServer(){
System.out.println("sendXMLToServer");
String strURL = "http://localhost:9080/MockServerMachine/sendXMLPost";
// Get file to be posted
String strXMLFilename = "output.xml";
File input = new File(strXMLFilename);
// Prepare HTTP post
System.out.println("junaud url "+ strURL);
PostMethod post = new PostMethod(strURL);
// Request content will be retrieved directly
// from the input stream
// Per default, the request content needs to be buffered
// in order to determine its length.
// Request body buffering can be avoided when
// content length is explicitly specified
try {
post.setRequestHeader("Content-type","application/xml");
post.setRequestHeader("Accept","application/xml");
post.setRequestEntity(new InputStreamRequestEntity(
new FileInputStream(input), input.length()));
HttpClient httpclient = new HttpClient();
int result = httpclient.executeMethod(post);
String xmlResponse = post.getResponseBodyAsString();
// Display status code
System.out.println("Response status code jun: " + result);
// Display response
System.out.println("Response body: ");
System.out.println(post.getResponseBodyAsString());
post.releaseConnection();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This is the server side:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//InputStream in = request.getInputStream();
//URL xmlUrl = new URL(request.getRequestURL().toString());
//InputStream in = xmlUrl.openStream();
response.setContentLength(100);
// PostMethod po = new PostMethod(request.getRequestURL().toString());
// System.out.println("kikmk = "+po.getRequestEntity());
try {
// read this file into InputStream
//InputStream inputStream = new FileInputStream("c:\\file.xml");
InputStream inputStream = request.getInputStream();
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File("c:\\junaidAhmedJameel.xml"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
System.out.println(new String (bytes));
System.out.println(read);
out.write(bytes, 0, read);
}
inputStream.close();
out.flush();
out.close();
System.out.println("New file created!");
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
Can anyone help me out here? Any sample client/server example for sending XML over HTTP would be great.
Ah, spotted it. Look here:
OutputStream out = new FileOutputStream(new File("c:\\junaidAhmedJameel.xml"));
That's just going to write to the local disk. You're not writing any content to the response stream. It's not clear what you want to write to the response stream, but there's a conspicuous absence of calls to response.getWriter() or response.getOutputStream().
You're setting the content length to 100, but not actually sending any content. Note that hard-coding the content-length is almost certainly the wrong thing to do anyway... but it's definitely the wrong thing to do when you're not sending any content...
You never generate any response content in your server code. You just set the length to 100.
Related
I have a REST endpoint that has to be accessed to retrieve a resource (image, document, ...).
#RequestMapping(value = "/attachement", method = RequestMethod.GET)
#ResponseBody
public Object getTrademarkAttachement(HttpServletResponse response, HttpServletRequest request) {
//TODO : Retrieve bytes from microservice url
//TODO : Send bytes to frontend page
}
For retrieving this document, I want to do it via streaming . I don't want to store in memory the info . I want to , as I get the info, send the bytes as a response . My version of spring MVC is Spring MVC 3.2 and my version of java is java 7 . Is it possible to achieve this ? could you give any clue to start investigating ? . I know I'm giving little details about implementation but I'm starting with this point and I would want to get some ideas from you .
EDIT 1 :
I have achieved half of the problem . Retrieving different blocks of the url . I have used the following code
#Override
public byte[] getTrademarkAttachement() {
String urlSample = "http://testUrl.com";
HttpURLConnection httpConn = null;
String line = null;
try {
httpConn = (HttpURLConnection) new URL(urlSample).openConnection();
InputStream ins = httpConn.getInputStream();
BufferedReader is = new BufferedReader(new InputStreamReader(ins));
while ((line = is.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpConn.disconnect();
}
return null;
}
Being able to have access to the inputstream , the part that is left is returning each of this lines that I'm reading , so I can stream the response . I have to look for a method in spring MVC that gives a partial response .
Since you can get the InputStream, you should be able to return an OutputStream as a response to the request. Take a look at this (https://stackoverflow.com/a/27742486/):
#RequestMapping(value = "/attachement", method = RequestMethod.GET)
#ResponseBody
public void getAttachment(OutputStream out) {
InputStream in = ; // Set this to the InputStream from HTTP as your provided example
byte[] buffer = new byte[1024]; // You will need a small buffer mem though
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
in.close();
out.flush();
}
Ok , I have solved my problem . I attach the solution . Maybe it's useful to anybody.
Controller
#RequestMapping(value="/eutm/{trademarkId}/snapshots/{historyId}/attachements/{attachementId}", method = RequestMethod.GET)
#ResponseBody
public void getTrademarkAttachement(HttpServletResponse response, #PathVariable String trademarkId, #PathVariable String historyId, #PathVariable String attachementId) {
try {
registerService.getTrademarkAttachement(trademarkId, historyId, attachementId, LanguageController.getLocale(), response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
Service
#Override
public void getTrademarkAttachement(String trademarkId, String historyId, String attachementId, Locale locale, ServletOutputStream outputStream) {
URI uri = loadHistoryUri(generateUri(REGISTER_BASE_MS_URL, REGISTER_HISTORY_ENTRY_TM_ATTACHEMENT_WS_URL, trademarkId, historyId, attachementId), locale.getLanguage());
HttpURLConnection httpConn = null;
String line = null;
InputStream ins = null;
try {
httpConn = (HttpURLConnection) new URL(uri.toString()).openConnection();
ins = httpConn.getInputStream();
BufferedReader is = new BufferedReader(new InputStreamReader(ins));
while ((line = is.readLine()) != null) {
outputStream.write(line.getBytes());
}
outputStream.flush();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
httpConn.disconnect();
if(ins != null){
try {
ins.close();
} catch (IOException e) {
logger.error("Bad close of inputStream ins");
}
}
}
}
This way, as it reads lines from inputStream ( url to retrieve via GET connection ), it writes it directly to the response via outputStream . It doesn't send bit to bit as in reactive mode , so the user is not getting the info directly, but I think that with Spring MVC 3.2 and Java 7 is the most approximate way to avoid elements in memory .
I am developing a software in which images should be upload from android to java. so far I have developed the following client on android:
String url=params[0];
String filePath=params[1];
File file=new File(filePath);
MultipartEntityBuilder multipartEntityBuilder=MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addPart("file", new FileBody(file));
HttpPut httpPut=new HttpPut(url);
HttpClient httpclient = new DefaultHttpClient();
httpPut.setEntity(multipartEntityBuilder.build());
HttpResponse response;
try {
response = httpclient.execute(httpPut);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result= convertStreamToString(instream);
instream.close();
return result;
}
} catch (Exception e) {
}
return null;
}
and the server is:
String path=Server.imagesPath+Utilities.getRandomString(10)+".jpg";
InputStream inputStream= arg0.getRequestBody();
File file=new File(path);
Files.copy(inputStream, file.toPath());
String response="OK";
try{
arg0.sendResponseHeaders(200, response.length());
OutputStream outputStream=arg0.getResponseBody();
outputStream.write(response.getBytes());
outputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The image is completely copied to the server but it is damaged and it can not be viewed. What is the problem?
It looks as though the upload is being done as a multipart form, which allows you to insert images as part of the data being sent; but the server is reading it as a pure octet stream rather than a multipart form.
You need to choose one or the other. Either interpret it as form data on the server, or just send the data as a stream rather than as form data.
I'd suggest having a look at Apache Commons FileUpload, which will simplify lots of this.
You can also use multiple data part entity for image uploading
you can see complete demo here: http://niravranpara.blogspot.in/2012/11/upload-video-in-server.html
I could finally solve the problem using this article:
Android Code to Upload & Download large files to server
the code I used on the Android was:
String urlString=params[0];
String path=params[1];
File file=new File(path);
int maxBufferSize=1024;
URL url=null;
try {
url=new URL(urlString);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpURLConnection connection=null;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
try {
connection.setRequestMethod("PUT");
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connection.setRequestProperty("Content-Type", "image/jpg");
OutputStream outputStream=null;
FileInputStream fileInputStream=null;
byte[] buffer;
int bytesRead,bytesAvailable,bufferSize;
try {
outputStream=connection.getOutputStream();
fileInputStream=new FileInputStream(file);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while(bytesRead > 0){
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.d("test Response Code ",Integer.toString(serverResponseCode));
Log.d("test Response Message ", serverResponseMessage);
} catch (IOException e) {
Log.d("test", e.getMessage());
}
I have a Servlet in Tomcat that reads binary file upload in the doPost method. The server code simplifies to:
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Received post request");
int read;
byte[] buffer = new byte[10*1024];
try {
InputStream inputStream = req.getInputStream();
while ((read = inputStream.read(buffer, 0, buffer.length)) != -1) {
/* do stuff */
}
resp.setStatus(200);
} catch (Exception e) {
resp.setStatus(500);
}
}
There are client applications that use this to servlet to upload a file. Very frequently, I'm getting a java.net.SocketTimeoutException on inputStream.read()
I would like to write a test client app to trigger this on the server side exception.
I tried:
public static void triggerTimeOut() {
HttpURLConnection urlConn = null;
try {
URL me = new URL("http://localhost:8080/uploadData");
urlConn = (HttpURLConnection)me.openConnection();
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
OutputStreamWriter sw = new OutputStreamWriter(urlConn.getOutputStream());
String[] data = new String[] {"line 1", "line 2"};
System.out.println(urlConn.getReadTimeout());
while(true) {
sw.write(data[0]);
sw.flush();
System.out.println(data[0]);
Thread.sleep(120000);
// break;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
System.out.println(urlConn.getResponseCode());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
But the timeout is never triggered, and in the server logs, I don't even get the "Received post request", even after i kill the client app. The debug line does get printed if I comment sleep, and uncomment break.
What kind of adjustments (on either tomcat or client) need to be done so I can get the server read to throw SocketTimeoutException? The HTTP Connector is set to connectionTimeout="5000" in server.xml. It's deliberately set shorter than the default 20000.
I'm trying to recreate the scenario for testing purposes.
I wrote this AsyncTask class that sends an array of POST data to my php server with no problem. Now I want to extend it so that it also sends a file to same script (I have already the receive handling in the php file). What I mean is I want it to post DATA + FILE in one go. Something like multipart entity or something from HTML action to php script.
What would I need to add to this class so it can upload a file with other things?
public class UpdateSnakeGameStatusTask extends AsyncTask<String, Integer, HttpResponse> {
private Context mContext;
private ArrayList<NameValuePair> mPairs;
/**
* #param context The context that uses this AsyncTask thread
* #param postPairs <b>NameValuePair</b> which contains name and post data
*/
public UpdateSnakeGameStatusTask(Context context, ArrayList<NameValuePair> postPairs) {
mContext = context;
mPairs = new ArrayList<NameValuePair>(postPairs);
}
#Override
protected HttpResponse doInBackground(String... params) {
HttpResponse response = null;
HttpPost httppost = new HttpPost(params[0]); //this is the URL
try {
httppost.setEntity(new UrlEncodedFormEntity(mPairs));
HttpClient client = new DefaultHttpClient();
response = client.execute(httppost);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
Ok as #greenapps suggested (credit goes to him) I solved like this.
Well not entirly solved, because I have to decode the file content at server side and save it manually on server.
so I jsut added the file content to the BasicNameValuePair that I already had:
String fileAsBase64 = Base64.encodeToString( convertToByteArray(mFile)
, Base64.DEFAULT);
mPostPairs.add(new BasicNameValuePair("filecontent", fileAsBase64));
And this is the method that converts it to byte array:
/**
* Reads a file and returns its content as byte array
* #param file file that should be returned as byte array
* #return byte[] array of bytes of the file
*/
public static byte[] convertTextFileToByteArray(File file) {
FileInputStream fileInputStream = null;
byte[] bFile = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
}catch(Exception e){
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
fileInputStream = null;
}
}
return bFile;
}
At the server side I do this:
$content = imap_base64 ($_POST["filecontent"]);
that takes care of decoding the content back to normal.
Hope this helps someone else too
Related to this question which is about how to send a binary file to a client. I am doing this, actually my method #Produces("application/zip"), and it works well for the browser client. Now I'm trying to write some automated tests against the rest service, using the Wink client. So my question is not how to send the file to the client, but for how to consume the file, as a java rest client (in this case Apache Wink).
My resource method looks something like the below... Once I have a Wink ClientResponse object, how can I get the file from it so I can work with it?
#GET
#Path("/file")
#Produces("application/zip")
public javax.ws.rs.core.Response getFile() {
filesToZip.put("file.txt", myText);
ResponseBuilder responseBuilder = null;
javax.ws.rs.core.Response response = null;
InputStream in = null;
try {
in = new FileInputStream( createZipFile( filesToZip ) );
responseBuilder = javax.ws.rs.core.Response.ok(in, MediaType.APPLICATION_OCTET_STREAM_TYPE);
response = responseBuilder.header("content-disposition", "inline;filename="file.zip").build();
} catch( FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
return response;
The method that actually creates the zip file looks like this
private String createZipFile( Map<String,String> zipFiles ) {
ZipOutputStream zos = null;
File file = null;
String createdFileCanonicalPath = null;
try {
// create a temp file -- the ZIP Container
file = File.createTempFile("files", ".zip");
zos = new ZipOutputStream( new FileOutputStream(file));
// for each entry in the Map, create an inner zip entry
for (Iterator<Map.Entry<String, String>> it = zipFiles.entrySet().iterator(); it.hasNext();){
Map.Entry<String, String> entry = it.next();
String innerFileName = entry.getKey();
String textContent = entry.getValue();
zos.putNextEntry( new ZipEntry(innerFileName) );
StringBuilder sb = new StringBuilder();
byte[] contentInBytes = sb.append(textContent).toString().getBytes();
zos.write(contentInBytes, 0, contentInBytes.length);
zos.closeEntry();
}
zos.flush();
zos.close();
createdFileCanonicalPath = file.getCanonicalPath();
} catch (SecurityException se) {
se.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (zos != null) {
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return createdFileCanonicalPath;
}
You can consume it simply as input stream and use ZipInputStream to unzip it.
Here's example using Apache HTTP Client:
HttpClient httpclient = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
get.addHeader(new BasicHeader("Accept", "application/zip"));
HttpResponse response = httpclient.execute(get);
InputStream is = response.getEntity().getContent();
ZipInputStream zip = new ZipInputStream(is);