Here is client code
public static void uploadFiles() {
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get(Parameter.UPLOAD_FILES_DIR), "{*.dat}")) {
for (Path path : ds) {
System.out.println(path);
URL url = new URL(Parameter.UPLOAD_URL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setConnectTimeout(1000 * 20);
conn.setReadTimeout(1000 * 20);
send(conn, path);
receive(conn);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void send(HttpURLConnection conn, Path path) throws Exception {
try (
BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(path.toFile()))
) {
byte[] buffer = new byte[1024];
int c = 0;
while ((c = in.read(buffer)) != -1) {
out.write(buffer, 0, c);
}
out.flush();
}
}
public static void receive(HttpURLConnection conn) throws Exception {
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String str;
while ((str = in.readLine()) != null) {
System.out.println(str);
}
if (HttpURLConnection.HTTP_OK != conn.getResponseCode()) {
throw new Exception("Uploader response code: " + conn.getResponseCode());
}
}
}
Here is Servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Post request");
System.out.println(request.getContentLength());
try (BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
) {
String str;
while ((str = br.readLine()) != null) {
System.out.print(str);
}
} catch (Exception ex) {
ex.printStackTrace();
}
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()))) {
bw.write("Close connection!!!");
}
}
When i run client code in server console out appears
Post refquest
-1
request.getContentLength() always return -1
Why i cant send bytes to the servlet? Here is contains of file which bytes i am trying to send
["192","2","3","4","5","6","7","8","9","US"] ["194","2","3","4","5","6","7","8","9","US"]
Resovled. Problem was in "/" symbol in the end of url. it was absent. But in this case servlet has responded.
Related
From my Tomcat's servlet I execute an https connection to an external servlet.
This is the code:
HttpsURLConnection hpcon = null;
try {
URL url = new URL(surl);
hpcon = (HttpsURLConnection) url.openConnection();
hpcon.setRequestMethod("POST");
hpcon.setDoInput(true);
hpcon.setDoOutput(true);
hpcon.setUseCaches(false);
hpcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
OutputStreamWriter wr = new OutputStreamWriter(hpcon.getOutputStream());
String params = "user=" + URLEncoder.encode(user, "UTF-8");
params += "&psswd=" + URLEncoder.encode(pssw, "UTF-8");
params += "&metodo=" + URLEncoder.encode(metodo, "UTF-8");
wr.write(params);
wr.flush();
wr.close();
hpcon.connect();
int respCode = hpcon.getResponseCode();
if (respCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(hpcon.getInputStream()));
String response = "";
String output;
while ((output = br.readLine()) != null) {
response += output;
}
if (response.indexOf("-") > 0) {
response = "-12";
System.out.println("ret = -12 - response = " + response);
}
br.close();
} else {
ret = "-11";
System.out.println("ret = -11 - respCode = " + respCode);
}
} catch (Exception e) {
e.printStackTrace();
ret = "-10";
System.out.println("ret = -10");
} finally {
if (hpcon != null) {
hpcon.disconnect();
}
}
Where surl is the full url of a servlet present in a different domain and the three parameters are read from a db table (the third really is fixed and is the operation that is make by the external servlet).
The result is:
ret = -11 - respCode = 404
Before make the connection I turn off the certificate's verify using the above code:
try {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (Exception e) {
e.printStackTrace();
}
If I execute the same servlet manually from a browser with parameters in get mode all run correctly.
I tried to execute it on my code using the get mode and passing the three parameters in query string, but the result is the same.
How can I do to resolve the problem?
I am developing a Windows phone 8 app that needs to upload photos to amazon s3 storage. However, I find that this is impossible since the HttpClient time out after about 60 seconds regardless of what timeout setting I use.
Is there really no way to upload large files from Windows Phone?
BackgroundTransferRequest is useless since it cannot send the neccessary metadata with file uploads.
I use this code (which times out):
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(30);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, m_uploadUrl);
httpContent.Headers.Add("Keep-Alive", "true");
request.Content = httpContent; // 3-5 Mb file
response = await httpClient.SendAsync(request);
statusCode = response.StatusCode;
}
I also tried PostAsync(), but same result. After about 60 sec the call completes with a status code 400 or 404. This is not a server timeout. IPhone and Android apps use the same service. No problems there.
Any ideas on how to upload files that takes more than 60 seconds to send?
I too faced similar things. The timeout glitch.
Check if you could use another class instead of HttpClient.
WebClient may be.
Check if this helps you:
http://blog.anthonybaker.me/2013/06/how-to-upload-file-from-windows-phone.html
and even this:
http://chriskoenig.net/2011/08/19/upload-files-from-windows-phone/
I got things working for me with those.
I've used several days now to implement a new uploader and get all the details working. I used HttpWebRequest with the async methods and split the file into chuncks. Finally I got it working and it uploads without the timeout. Here is the complete code:
using System;
using Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Services
{
public class UploadData
{
public Stream PostStream { get; set; }
public Stream FileStream { get; set; }
public byte[] HeaderBytes {get; set;}
public byte[] FooterBytes {get; set;}
public byte[] Buffer { get; set; }
public Photo Upload { get; set; }
public int BytesWritten { get; set; }
}
public class UploadEventArgs : EventArgs
{
public Photo Upload { get; set; }
public int Progress { get; set; }
}
public class UploadService
{
public delegate void CompletedEventHandler(object sender, UploadEventArgs e);
public event CompletedEventHandler UploadCompleted;
public delegate void ProgressEventHandler(object sender, UploadEventArgs e);
public event ProgressEventHandler ProgressChanged;
private static string contentType = "multipart/form-data; boundary={0}";
private static string headerString = "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\nContent-Type: Content-Type: application/octet-stream\r\n\r\n";
private HttpWebRequest m_request;
private static string boundarystr;
private UploadData m_uploadData;
private bool m_isStopped;
public async Task StartUpload(Photo upload, Uri uri, Dictionary<string, string> parameters)
{
try
{
m_isStopped = false;
var fileStream = (await upload.File.OpenReadAsync()).AsStreamForRead();
var uploadData = new UploadData();
boundarystr = "---------------------------" + DateTime.Now.Ticks.ToString("x");
string para = GetParamsString(parameters);
string headAndParams = para + String.Format(headerString, HttpUtility.UrlEncode(upload.File.Name));
var headerBytes = System.Text.Encoding.UTF8.GetBytes(headAndParams);
var footerBytes = Encoding.UTF8.GetBytes("\r\n--" + boundarystr + "--\r\n");
uploadData.Upload = upload;
uploadData.FileStream = fileStream;
uploadData.FooterBytes = footerBytes;
uploadData.HeaderBytes = headerBytes;
uploadData.BytesWritten = 0;
m_uploadData = uploadData;
m_request = (HttpWebRequest)WebRequest.Create(uri);
m_request.Method = "POST";
m_request.AllowWriteStreamBuffering = false;
m_request.ContentType = string.Format(contentType, boundarystr);
m_request.ContentLength = fileStream.Length + headerBytes.Length + footerBytes.Length;
var asyncResult = m_request.BeginGetRequestStream((ar) => { GetRequestStreamCallback(ar, uploadData); }, m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Start upload failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult, UploadData uploadData)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = request.EndGetRequestStream(asynchronousResult);
postStream.Write(uploadData.HeaderBytes, 0, uploadData.HeaderBytes.Length);
var args = new UploadEventArgs();
args.Upload = uploadData.Upload;
args.Progress = 1;
OnProgressChanged(args);
uploadData.PostStream = postStream;
WriteNextChunck(uploadData);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Header write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
m_uploadData.FileStream.Close();
m_uploadData.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void WriteNextChunck(UploadData upload)
{
try
{
if ((upload.FileStream.Length - upload.BytesWritten) >= 16 * 1024)
{
upload.Buffer = new byte[16 * 1024];
}
else
{
// Last part
upload.Buffer = new byte[upload.FileStream.Length - upload.BytesWritten];
}
upload.FileStream.Read(upload.Buffer, 0, (int)upload.Buffer.Length);
upload.PostStream.BeginWrite(upload.Buffer, 0, upload.Buffer.Length, BeginWriteCallback, upload);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Buffer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
upload.FileStream.Close();
upload.PostStream.Close();
OnUploadComplete(argsStopped);
}
}
private void BeginWriteCallback(IAsyncResult ar)
{
try
{
var upload = ar.AsyncState as UploadData;
upload.PostStream.EndWrite(ar);
upload.BytesWritten += upload.Buffer.Length;
var args = new UploadEventArgs();
args.Upload = upload.Upload;
args.Progress = (int)(((decimal)upload.BytesWritten / (decimal)upload.FileStream.Length) * 100);
OnProgressChanged(args);
if (m_isStopped)
{
upload.FileStream.Close();
upload.PostStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload stopped");
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
return;
}
// write next chunck
if (upload.BytesWritten < upload.FileStream.Length)
{
WriteNextChunck(upload);
}
if (upload.BytesWritten >= upload.FileStream.Length)
{
WriteFooter(upload);
}
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Upload write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void WriteFooter(UploadData upload)
{
try
{
upload.PostStream.Write(upload.FooterBytes, 0, upload.FooterBytes.Length);
upload.PostStream.Close();
var asyncResult = m_request.BeginGetResponse(new AsyncCallback(GetResponseCallback), m_request);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = new Exception("Footer write failed: " + ex.Message);
var argsStopped = new UploadEventArgs();
argsStopped.Upload = m_uploadData.Upload;
OnUploadComplete(argsStopped);
}
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
m_uploadData.FileStream.Close();
m_uploadData.Upload.UploadInfo.StatusCode = response.StatusCode;
if (response.StatusCode == HttpStatusCode.NoContent)
{
m_uploadData.Upload.UploadInfo.Exception = null;
}
else
{
m_uploadData.Upload.UploadInfo.Exception = new Exception(responseString);
}
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
args.Progress = 100;
OnUploadComplete(args);
}
catch (Exception ex)
{
m_uploadData.Upload.UploadInfo.StatusCode = HttpStatusCode.NotFound;
m_uploadData.Upload.UploadInfo.Exception = ex;
var args = new UploadEventArgs();
args.Upload = m_uploadData.Upload;
OnUploadComplete(args);
}
}
private string GetParamsString(Dictionary<string, string> parameters)
{
bool needsCLRF = false;
string result = "";
foreach (var param in parameters)
{
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
// Skip it on the first parameter, add it to subsequent parameters.
if (needsCLRF)
result += "\r\n";
needsCLRF = true;
string prm = string.Format("--{0}\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Disposition: form-data; name={1}\r\n\r\n{2}",
boundarystr,
param.Key,
param.Value);
result += prm;
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundarystr + "\r\n";
result += footer;
return result;
}
protected virtual void OnUploadComplete(UploadEventArgs e)
{
if (UploadCompleted != null)
UploadCompleted(this, e);
}
protected virtual void OnProgressChanged(UploadEventArgs e)
{
if (ProgressChanged != null)
ProgressChanged(this, e);
}
public void Stop()
{
m_isStopped = true;
}
}
}
My server receive some TCP/IP data and response to client:
private static void startClient(TcpClient clientSocket)
{
NetworkStream networkStream = null;
DateTime fecha = DateTime.Now;
try
{
clientSocket.NoDelay = true;
networkStream = clientSocket.GetStream();
string receiveData = readData(clientSocket);
string responseData = "abc"; //ProcessData(receiveData);
if (responseData != null)
writeData(networkStream, responseData);
}
catch (SocketException e)
{
throw;
}
finally
{
networkStream.Close();
}
}
private static string readData(TcpClient tcpClient)
{
try
{
var bytesFrom = new byte[tcpClient.ReceiveBufferSize];
StringBuilder dataFromClient = new StringBuilder();
int readCount;
while ((readCount = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize)) != 0)
{
dataFromClient.Append(Encoding.ASCII.GetString(bytesFrom, 0, readCount));
}
//int bytesRead = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize);
//string dataFromClient = Encoding.ASCII.GetString(bytesFrom, 0, bytesRead);
return dataFromClient.ToString();
}
catch (SocketException e)
{
throw;
}
}
private static void writeData(NetworkStream networkStream, string dataToClient)
{
Byte[] sendBytes = null;
try {
sendBytes = Encoding.ASCII.GetBytes(dataToClient);
networkStream.Write(sendBytes,0, sendBytes.Length);
networkStream.Flush();
}
catch(SocketException e)
{
throw;
}
}
With this solution the client never receives the response sent:
http://postimg.org/image/6srtslf2f/
However changing the reception to a single call to NetworkStream.Read ...
private static string readData(TcpClient tcpClient)
{
try
{
var bytesFrom = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize);
string dataFromClient = Encoding.ASCII.GetString(bytesFrom, 0, bytesRead);
return dataFromClient.ToString();
}
catch (SocketException e)
{
throw;
}
}
... the client receives the response
http://postimg.org/image/uih9hadfr/
UPDATE
I found solution here. I´ve fixed it using 2/3 ways described . First handle EOS end message. Seccond is setting receive timeout if client works bad and sends bad data without EOS:
private static string readData(TcpClient tcpClient)
{
var clientStream = tcpClient.GetStream();
var dataFromClient = string.Empty;
var buffer = new byte[RECEIVE_BUFFER_SIZE];
if (!clientStream.CanRead)
return "";
tcpClient.ReceiveTimeout = RECEIVE_TIMEOUT;
try
{
int readCount;
while ((readCount = clientStream.Read(buffer, 0, buffer.Length)) != 0)
{
dataFromClient += Encoding.ASCII.GetString(buffer, 0, readCount);
if (dataFromClient.EndsWith(EOS))
return dataFromClient;
}
return dataFromClient.ToString();
}
catch (Exception ex)
{
var socketExept = ex.InnerException as SocketException;
if (socketExept != null && socketExept.SocketErrorCode == SocketError.TimedOut)
Logger.Warn(string.Format("Se excedio el timeout de recepcion: {0} ms",RECEIVE_TIMEOUT));
else
Logger.Error(string.Format("Error leyendo el mensaje recibido"), ex);
return dataFromClient.ToString();
}
}
I am writing a web app to process a command line commands and display the out put.
I've tried using exec() but it doesn't seem to work.
Process process;
process = Runtime.getRuntime().exec(commands);
String line;
is = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = is.readLine()) != null)
out.println(line);
added buffers and try cases, works great now.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String[] commands = {"date"};
BufferedReader is = null;
BufferedReader es = null;
try
{
Process process;
process = Runtime.getRuntime().exec(commands);
String line;
is = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = is.readLine()) != null)
out.println(line);
es = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while((line = es.readLine()) != null)
System.err.println(line);
int exitCode = process.waitFor();
if (exitCode == 0)
out.println("It worked");
else
out.println("Something bad happend. Exit code: " + exitCode);
} //try
catch(Exception e)
{
out.println("Something when wrong: " + e.getMessage());
e.printStackTrace();
} //catch
finally
{
if (is != null)
try { is.close(); } catch (IOException e) {}
if (es != null)
try { es.close(); } catch (IOException e) {}
} //finally
}
How to redirect Glassfish server output into HttpServletResponse.out? I am making servlet in NetBeans.
here is a working example, just expose this as a servlet
public class ReadLogs extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=UTF-8";
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.append("<html>\n<head>\n\n");
out.append("<script>function toBottom()" + "{"
+ "window.scrollTo(0, document.body.scrollHeight);" + "}");
out.append("\n</script>");
out.append("\n</head>\n<body onload=\"toBottom();\">\n<pre>\n");
try {
File file = new File("C:\\pathToServerLogFile");
BufferedReader in = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
while (in.ready()) {
String x = in.readLine();
sb.append(x).append("<br/>");
}
in.close();
out.append("\n</pre>\n</body>\n</html>");
out.close();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
UPDATE
If you need to print only the last portion of the file use this after line "in.close();"
//print only 1MB Oof data
if(sb.length()>1000000){
out.append(sb.substring(sb.length()-1000000, sb.length()));
}else{
out.append(sb.toString());
}
So.. to print only lines which appeared after invoking script I've made such code:
BufferedReader reader = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
int lines = 0;
while (reader.readLine() != null) {
lines++;
}
reader.close();
BufferedReader reader2 = new BufferedReader(new FileReader("/path/to/server/log/server.log"));
String strLine;
int i = 0;
while (i != lines) {
reader2.readLine();
i++;
}
while ((strLine = reader2.readLine()) != null) {
out.println(stringToHTMLString(strLine));
out.println("<br>");
}
reader2.close();
When servlet starts it counts lines in server log (saves it in variable i), then after clicking on action form it read lines which indexes are higher than i and displays it on html page. I've used function stringToHTMLString which I found somewhere on stackoverflow.
Greets.