我用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时候,就开始就收不到了.

解决方案 »

  1.   

    在if中返回的字符串是不是不符合传输或接收要求,所以收不到当上传内容在>95K时候, 服务端是执行到哪里?
      

  2.   


    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();
            }
        }
    }
      

  3.   


    解决是解决了,但是还是有点模糊道理.
    解决方法,就是在输入返回之前,先将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 ;
    }
    }
    }
    }
      

  4.   

    HTTP是单通道,还是什么原因,导致的呀.
    求高人来指明真相.
      

  5.   

    既然大文件和小文件都能走到 out.write(str);
    区别在哪呢?返回的str吗?
      

  6.   

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

  7.   

    的确,貌似response对象已经输出返回了,难道就像你说的单通道,服务端的输出流被输入流堵塞了导致客户端接收不到返回?那为什么文件小的时候没问题呢,要再研究一下
      

  8.   


    我的想方法是这样的:其实,他们会自己收.
    当小文件的时候,我在走逻辑的时候,已经收完了.
    所以返回是OK的.当是大文件的时候,逻辑走的很快.(比收文件快),
    所以逻辑上很快返回了,然后write了.
    但此时文件还没有收完,然后就write了,估计是有一单通道或者什么锁的概念.
    等忙过边阵,再来细细看看.有人明白,也希望能来指点一下.
      

  9.   


    不.当小文件的时候,我在走逻辑的时候,已经收完了.
    所以返回是OK的.当是大文件的时候,逻辑走的很快.(比收文件快),
    所以逻辑上很快返回了,然后write了.(此时因为文件比较大,InputStream里面的文件内容还没有收完.)
      

  10.   

    调试了一下程序,发现是既能接收文件,也能收到返回的客户端: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();
    }}
      

  11.   

    服务端发错了,重发服务端: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();
        }
    }}
      

  12.   


    如果改成如下还可以吗?
      ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
     
       //     writeLogFile(request);  不读直接返回
    out.writeChars("OK!");
    out.flush();
    out.close();
    另外,你post发送,get也能收到呀?
      

  13.   


    试过了,可以,你也可以自己运行验证一下,接下来要对比一下。其实就是post收到,只是在post中调用get而已,和直接在doPost中处理没区别。
      

  14.   


    你在本地是试的是吧?我在本地试也是可以.可是放到内网上别外一台电脑,就不行了.
    别一台电脑的环境是nginx+tomcat
      

  15.   

    是本地,按理本地和网络对于code level不应该有什么影响才对(是否跨网对于程序端是不可见的)因为也没有查到特别声明楼主此一现象的文章,怀疑可能这不是一种普遍现象或标准应对方法。等有时间了再好好查一查。