首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

HTTP POST 发送资料时收不到返回

2012-12-17 
HTTP POST 发送文件时收不到返回.我用HttpURLConnection来模拟HTTP的POST请求,并在InputStream里面,发送文

HTTP POST 发送文件时收不到返回.
我用HttpURLConnection来模拟HTTP的POST请求,并在InputStream里面,发送文件.
本来想先描述问题的.可是模述不清,先上代码
发送的代码:


public static String postByte() {
byte[] param = ZhsqTestHttp.readFileByBytes("D:\\logs\\tmsInfoLog.log");
URL url = null;
HttpURLConnection httpURLConnection = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL(POST_URL);
httpURLConnection = (HttpURLConnection) url.openConnection();

// 设置连接属性
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);

// 设置请求属性
httpURLConnection.setRequestProperty("Content-length", "" + param.length);
httpURLConnection.setRequestProperty("Content-Type", "application/octet-stream");
httpURLConnection.setRequestProperty("ID", "48XYHA8OVG5LNGAY9RRH97A6ESL9LNL5");

// 建立输出流,并写入数据
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(param);
outputStream.flush();
outputStream.close();

BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));// 设置编码,否则中文乱码
String line = "";
while ((line = reader.readLine()) != null) {
//返回打印处
System.out.println(line);
}
reader.close();

} catch (Exception e) {
e.printStackTrace();
sb.append("0");

} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();

}
System.out.println(sb.toString());
return sb.toString();
}



服务器处理端:

public String answer(String ID,HttpServletRequest request)throws ParamException {
ResultProxy result = new ResultProxy();
result.setCodeAndMsg(MsgCodeInfo.SUSS);
if (StringHelper.isNullOrEmpty(ID)) {
result.setCodeAndMsg(MsgCodeInfo.PARA_NULL_OR_ERROR);
result.setMsg("actionID 或 status,"+result.getMsg());
return JSON.toJSONString(result);
}else{
this.writeLogFile(request,answerFile);
return "OK";
}
}


public String writeLogFile(HttpServletRequest request,String fileMd5){
try {

String fileName = DateHelper.getDateNumByNow() + DateHelper.getUUID()+".log";
String filepath = createDir();

InputStream inputStream = request.getInputStream();
FileOutputStream fos = new FileOutputStream(filepath+"/"+fileName);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
inputStream.close();
return fileName;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}


HTTP:输出方法:
public void outJSON(String str) {
//上线的时候,以JSON的方式进行传输.
try {
Object requestUUID = getRequest().getAttribute(MsgCodeInfo.PARA_REQUEST_UUID);
getResponse().setHeader("Pragma", "no-cache");
getResponse().setHeader("Cache-Control", "no-cache");


getResponse().setDateHeader("Expires", 0);
getResponse().setContentType("text/javascript;charset=utf-8");
this.addResponseLog(str, requestUUID.toString());//返回日志
} finally {
outSTR(str);
}
}

private final void outSTR(String str) {
PrintWriter out = null;
try {
out = getResponse().getWriter();{
out.write(str);
}
} catch (IOException e) {
logger.error("输出异常", e);
} finally {
if (out != null) {
out.flush();
out.close();
}
}
}




现在的问题是:
if (StringHelper.isNullOrEmpty(ID)) {
   //如果逻辑走到这里,终端就收不到返回.
    result.setCodeAndMsg(MsgCodeInfo.PARA_NULL_OR_ERROR);
    result.setMsg("actionID 或 status,"+result.getMsg());
    return JSON.toJSONString(result);
}else{
    //如果走到了这里,将文件读出来后.终端就能收到OK
    this.writeLogFile(request,answerFile);
    return "OK";
}

不明白是这是为什么?
求指导.

后面发现也不是,所有的都不行.当上传内容在>95K时候,就开始就收不到了.




[最优解释]
就是说,再小的文件,如果服务端不收而直接返回的话,客户端是接收不到消息的是吧?
[其他解释]
在if中返回的字符串是不是不符合传输或接收要求,所以收不到

当上传内容在>95K时候, 服务端是执行到哪里?
[其他解释]
有可能是提交方式问题了。
[其他解释]
引用:
3.上传内容在>95K时候, 服务端是执行到哪里? 
-->从日志上看.
private final void outSTR(String str) {
    PrintWriter out = null;
    try {
        out = getResponse().getWriter();{
            out.write(str);
        }
       System.out.println("这一行,都已被打印出来了")
    } catch (IOException e) {
        logger.error("输出异常", e);
    } finally {
        if (out != null) {
            out.flush();
            out.close();
        }
    }
} ……

既然大文件和小文件都能走到 out.write(str);
区别在哪呢?返回的str吗?
[其他解释]
引用:
在if中返回的字符串是不是不符合传输或接收要求,所以收不到

当上传内容在>95K时候, 服务端是执行到哪里?


1.在if中返回的字符串是不是不符合传输或接收要求,所以收不到
   --->在内容小的时候,都正常的,不管怎么样都正常.

2.当内容较大的时候,
if (StringHelper.isNullOrEmpty(ID)) {   //这里false的话.
    result.setCodeAndMsg(MsgCodeInfo.PARA_NULL_OR_ERROR);
    result.setMsg("actionID 或 status,"+result.getMsg());
    return JSON.toJSONString(result);
}else{       //将文件读出来后.终端就能收到OK,  也是正常的.
    this.writeLogFile(request,answerFile);


    return "OK";
}

3.当内容较大的时候,
if (StringHelper.isNullOrEmpty(ID)) {   //这里true的话.终段收不收到.(内容较小的时候能收到)
    result.setCodeAndMsg(MsgCodeInfo.PARA_NULL_OR_ERROR);
    result.setMsg("actionID 或 status,"+result.getMsg());   //所以觉得与内容无关.
    return JSON.toJSONString(result);
}else{       //不走这里,与这里无关.
    this.writeLogFile(request,answerFile);
    return "OK";
}


3.上传内容在>95K时候, 服务端是执行到哪里? 
-->从日志上看.
private final void outSTR(String str) {
    PrintWriter out = null;
    try {
        out = getResponse().getWriter();{
            out.write(str);
        }
       System.out.println("这一行,都已被打印出来了")
    } catch (IOException e) {
        logger.error("输出异常", e);
    } finally {
        if (out != null) {
            out.flush();
            out.close();
        }
    }
}
[其他解释]

引用:
有可能是提交方式问题了。


解决是解决了,但是还是有点模糊道理.
解决方法,就是在输入返回之前,先将InputStream读一遍.

code如下:

private final void outSTR(String str,HttpServletResponse response,HttpServletRequest request) {
this.cleanStream(request);
PrintWriter out = null;
try {
out = response.getWriter();{
out.write(str);
}
} catch (IOException e) {
logger.error("输出异常", e);
} finally {
if (out != null) {
out.flush();
out.close();
}
}
}

public void cleanStream(HttpServletRequest request){
byte[] buffer = new byte[1024];
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
while (inputStream.read(buffer) > 0) {
}
} catch (IOException e) {
e.printStackTrace();
return ;
}finally{
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return ;
}
}
}
}



[其他解释]
HTTP是单通道,还是什么原因,导致的呀.
求高人来指明真相.
[其他解释]
引用:
解决是解决了,但是还是有点模糊道理.
解决方法,就是在输入返回之前,先将InputStream读一遍.

你这里的读inputstream会对返回的response产生影响吗?应该也不会啊
[其他解释]
引用:
引用:解决是解决了,但是还是有点模糊道理.
解决方法,就是在输入返回之前,先将InputStream读一遍.


你这里的读inputstream会对返回的response产生影响吗?应该也不会啊



我也纠结,可确实是这样解决了.
[其他解释]
引用:
引用:引用:解决是解决了,但是还是有点模糊道理.
解决方法,就是在输入返回之前,先将InputStream读一遍.
你这里的读inputstream会对返回的response产生影响吗?应该也不会啊

我也纠结,可确实是这样解决了.

的确,貌似response对象已经输出返回了,难道就像你说的单通道,服务端的输出流被输入流堵塞了导致客户端接收不到返回?那为什么文件小的时候没问题呢,要再研究一下
[其他解释]
引用:
引用:引用:引用:解决是解决了,但是还是有点模糊道理.
解决方法,就是在输入返回之前,先将InputStream读一遍.
你这里的读inputstream会对返回的response产生影响吗?应该也不会啊

我也纠结,可确实是这样解决了.
的确,貌似response……


我的想方法是这样的:

其实,他们会自己收.
当小文件的时候,我在走逻辑的时候,已经收完了.
所以返回是OK的.

当是大文件的时候,逻辑走的很快.(比收文件快),
所以逻辑上很快返回了,然后write了.
但此时文件还没有收完,然后就write了,估计是有一单通道或者什么锁的概念.


等忙过边阵,再来细细看看.

有人明白,也希望能来指点一下.
[其他解释]
引用:
就是说,再小的文件,如果服务端不收而直接返回的话,客户端是接收不到消息的是吧?


不.

当小文件的时候,我在走逻辑的时候,已经收完了.
所以返回是OK的.

当是大文件的时候,逻辑走的很快.(比收文件快),
所以逻辑上很快返回了,然后write了.(此时因为文件比较大,InputStream里面的文件内容还没有收完.)
[其他解释]
引用:
引用:就是说,再小的文件,如果服务端不收而直接返回的话,客户端是接收不到消息的是吧?

不.

当小文件的时候,我在走逻辑的时候,已经收完了.
所以返回是OK的.

当是大文件的时候,逻辑走的很快.(比收文件快),
所以逻辑上很快返回了,然后write了.(此时因为文件比较大,InputStream里面的文件内容……

我是说小文件不收,能不收直接返回吗?这个要是有个可执行的例子就好测了。
[其他解释]
调试了一下程序,发现是既能接收文件,也能收到返回的

客户端:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


public class Test {

public static void main(String[] args) {
try {
postByte();
} catch (IOException e) {
e.printStackTrace();
}
}

public static String postByte() throws IOException {
FileInputStream fis = new FileInputStream(new File("test.txt"));
byte[] param = new byte[300*1024];

fis.read(param);

URL url = null;
HttpURLConnection httpURLConnection = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL("http://127.0.0.1:8080/WebTest/MyServlet");
httpURLConnection = (HttpURLConnection) url.openConnection();

// 设置连接属性
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);

// 设置请求属性
httpURLConnection.setRequestProperty("Content-length", ""
+ param.length);
httpURLConnection.setRequestProperty("Content-Type",
"application/octet-stream");
httpURLConnection.setRequestProperty("ID",
"48XYHA8OVG5LNGAY9RRH97A6ESL9LNL5");

// 建立输出流,并写入数据
OutputStream outputStream = httpURLConnection.getOutputStream();


outputStream.write(param);
outputStream.flush();
outputStream.close();

BufferedReader reader = new BufferedReader(new InputStreamReader(
httpURLConnection.getInputStream(), "utf-8"));// 设置编码,否则中文乱码
String line = "";
while ((line = reader.readLine()) != null) {
// 返回打印处
System.out.println(line);
}
reader.close();

} catch (Exception e) {
e.printStackTrace();
sb.append("0");
} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();

}
System.out.println(sb.toString());
return sb.toString();
}

}



服务端:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


public class Test {

public static void main(String[] args) {
try {
postByte();
} catch (IOException e) {
e.printStackTrace();
}
}

public static String postByte() throws IOException {
FileInputStream fis = new FileInputStream(new File("test.txt"));
byte[] param = new byte[300*1024];

fis.read(param);

URL url = null;
HttpURLConnection httpURLConnection = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL("http://127.0.0.1:8080/WebTest/MyServlet");
httpURLConnection = (HttpURLConnection) url.openConnection();

// 设置连接属性
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);

// 设置请求属性
httpURLConnection.setRequestProperty("Content-length", ""
+ param.length);
httpURLConnection.setRequestProperty("Content-Type",
"application/octet-stream");
httpURLConnection.setRequestProperty("ID",
"48XYHA8OVG5LNGAY9RRH97A6ESL9LNL5");

// 建立输出流,并写入数据
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(param);
outputStream.flush();
outputStream.close();

BufferedReader reader = new BufferedReader(new InputStreamReader(
httpURLConnection.getInputStream(), "utf-8"));// 设置编码,否则中文乱码
String line = "";
while ((line = reader.readLine()) != null) {
// 返回打印处
System.out.println(line);
}
reader.close();

} catch (Exception e) {
e.printStackTrace();
sb.append("0");
} finally {
if (httpURLConnection != null)
httpURLConnection.disconnect();

}
System.out.println(sb.toString());
return sb.toString();
}

}


[其他解释]
服务端发错了,重发

服务端:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;



import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {

/**
 * Constructor of the object.
 */
public MyServlet() {
super();
}

/**
 * Destruction of the servlet. <br>
 */
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}

/**
 * The doGet method of the servlet. <br>
 * 
 * This method is called when a form has its tag value method equals to get.
 * 
 * @param request
 *            the request send by the client to the server
 * @param response
 *            the response send by the server to the client
 * @throws ServletException
 *             if an error occurred
 * @throws IOException
 *             if an error occurred
 */
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doGet");

ObjectOutputStream out = new ObjectOutputStream(response
.getOutputStream());

writeLogFile(request);
out.writeChars("OK!");
out.flush();
out.close();

}

/**
 * The doPost method of the servlet. <br>
 * 
 * This method is called when a form has its tag value method equals to
 * post.
 * 
 * @param request
 *            the request send by the client to the server
 * @param response
 *            the response send by the server to the client
 * @throws ServletException
 *             if an error occurred
 * @throws IOException
 *             if an error occurred
 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doPost");
doGet(request, response);
}

/**
 * Initialization of the servlet. <br>
 * 
 * @throws ServletException
 *             if an error occurs
 */
public void init() throws ServletException {


// Put your code here
}

public void writeLogFile(HttpServletRequest request){
    try {
             
        InputStream inputStream = request.getInputStream();
        FileOutputStream fos = new FileOutputStream(new File("c:\\testaaa.log"));         
        byte[] buffer = new byte[1024];
        while (inputStream.read(buffer) > 0) {
            fos.write(buffer);
        }
        fos.flush();
        fos.close();
        inputStream.close();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
}

}


[其他解释]
引用:
服务端发错了,重发

服务端:
Java code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838……


如果改成如下还可以吗?


  ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
 
   //     writeLogFile(request);  不读直接返回
out.writeChars("OK!");
out.flush();
out.close();




另外,你post发送,get也能收到呀?





[其他解释]
引用:
引用:如果改成如下还可以吗?
另外,你post发送,get也能收到呀?

试过了,可以,你也可以自己运行验证一下,接下来要对比一下。

其实就是post收到,只是在post中调用get而已,和直接在doPost中处理没区别。


你在本地是试的是吧?

我在本地试也是可以.

可是放到内网上别外一台电脑,就不行了.
别一台电脑的环境是nginx+tomcat
[其他解释]
引用:
如果改成如下还可以吗?
另外,你post发送,get也能收到呀?


试过了,可以,你也可以自己运行验证一下,接下来要对比一下。

其实就是post收到,只是在post中调用get而已,和直接在doPost中处理没区别。
[其他解释]
引用:
你在本地是试的是吧?

我在本地试也是可以.

可是放到内网上别外一台电脑,就不行了.
别一台电脑的环境是nginx+tomcat 

是本地,按理本地和网络对于code level不应该有什么影响才对(是否跨网对于程序端是不可见的)

因为也没有查到特别声明楼主此一现象的文章,怀疑可能这不是一种普遍现象或标准应对方法。等有时间了再好好查一查。

热点排行
Bad Request.