jba*_*sta 9 binary post servlets http inputstream
我正在尝试编写一个Java Servlet来接收二进制数据请求并使用HttpServletRequest.getOutputStream()和回复它们HttpServletResponse.getInputStream().这适用于涉及通过HTTP POST连接向此Servlet响应的Silverlight客户端发送请求的项目.目前,为了测试Servlet,我正在用Java实现一个比Silverlight更熟悉的客户端.
问题是,在我的测试项目中,我将来自Servlet客户端的数据作为字节数组发送,并期望接收具有相同长度的字节数组 - 只是它没有,而是我得到一个字节.因此,我在这里发布相关的代码片段,希望你可以指出我在哪里做错了,并希望提供相关的参考书目来帮助我.
所以这里.
该客户端的servlet从一个非常简单的HTML页面处理与我作为前端使用表单POST请求.我并不太担心使用JSP等,而是专注于使Servlet之间的通信工作.
// client HttpServlet invokes this method from doPost(request,response)
private void process(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String firstName = (String) request.getParameter("firstname");
String lastName = (String) request.getParameter("lastname");
String xmlRequest = "<MyRequest><Person><Name Firstname=\""+firstName+"\" Lastname=\""+lastName+"\" /></Person></MyRequest>";
OutputStream writer = null;
InputStream reader = null;
try {
URL url = new URL("http://localhost:8080/project/Server");
URLConnection conn = url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
writer = conn.getOutputStream();
byte[] baXml = xmlRequest.getBytes("UTF-8");
writer.write(baXml, 0,baXml.length);
writer.flush();
// perhaps I should be waiting here? how?
reader = conn.getInputStream();
int available = reader.available();
byte[] data = new byte[available];
reader.read(data,0,available);
String xmlResponse = new String(data,"UTF-8");
PrintWriter print = response.getWriter();
print.write("<html><body>Response:<br/><pre>");
print.write(xmlResponse);
print.write("</pre></body></html>");
print.close();
} finally {
if(writer!=null)
writer.close();
if(reader!=null)
reader.close();
}
}
Run Code Online (Sandbox Code Playgroud)
该服务器的servlet处理HTTP POST请求.这是通过从上面的测试目的接收来自客户端Servlet的请求来完成的,但是将来我打算将它用于其他语言的客户端(特别是Silverlight).
// server HttpServlet invokes this method from doPost(request,response)
private void process(HttpServletRequest request, HttpServetResponse response)
throws ServletException, IOException {
ServletInputStream sis = null;
try {
sis = request.getInputStream();
// maybe I should be using a BufferedInputStream
// instead of the InputStream directly?
int available = sis.available();
byte[] input = new byte[available];
int readBytes = sis.read(input,0,available);
if(readBytes!=available) {
throw new ServletException("Oops! readBytes!=availableBytes");
}
// I ONLY GET 1 BYTE OF DATA !!!
// It's the first byte of the client message, a '<'.
String msg = "Read "+readBytes+" bytes of "
+available+" available from request InputStream.";
System.err.println("Server.process(HttpServletRequest,HttpServletResponse): "+msg);
String xmlReply = "<Reply><Message>"+msg+"</Message></Reply>";
byte[] data = xmlReply.getBytes("UTF-8");
ServletOutputStream sos = response.getOutputStream();
sos.write(data, 0,data.length);
sos.flush();
sos.close();
} finally {
if(sis!=null)
sis.close();
}
}
Run Code Online (Sandbox Code Playgroud)
BufferInputStream到目前为止,我一直坚持使用字节数组而不是使用s,因为我还没有决定是否使用例如Base64编码的字符串来传输数据,或者我是否会按原样发送二进制数据.
先感谢您.
小智 8
要将输入流复制到输出流,请使用标准方式:
InputStream is=request.getInputStream();
OutputStream os=response.getOutputStream();
byte[] buf = new byte[1000];
for (int nChunk = is.read(buf); nChunk!=-1; nChunk = is.read(buf))
{
os.write(buf, 0, nChunk);
}
Run Code Online (Sandbox Code Playgroud)
我能想到的一件事是你只读取request.getInputStream().available()字节,然后决定你已经拥有了一切。根据文档,available()将返回可以在不阻塞的情况下读取的字节数,但我没有看到任何提及这是否实际上保证是输入流的全部内容,因此我倾向于假设没有这样的作出保证。
我不确定如何最好地找出何时没有更多数据(也许Content-Length在请求中可以提供帮助?)而不冒着在 EOF 处无限期阻塞的风险,但我会尝试循环,直到从输入流中读取所有数据。为了测试该理论,您始终可以扫描输入以查找流中进一步出现的已知模式,可能与您获得的>首字母匹配。<
| 归档时间: |
|
| 查看次数: |
51986 次 |
| 最近记录: |