无法使用outputStreamWriter()从app向servlet发送字符串

时间:2014-02-01 08:55:41

标签: java android http java-ee servlets

我正在尝试从我的应用程序向Java servlet发送一个小字符串:

//Send user mobile number to the server.
EditText cinMobile = (EditText)findViewById(R.id.mobile_no);
String inputVal = cinMobile.getText().toString();

URL mobileurl = new URL(url);
URLConnection connection = mobileurl.openConnection();
connection.setDoOutput(true);

OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(inputVal);
out.close();

servlet应该通过doPost()接收值:

//Accept the phone number form the app
int length = request.getContentLength();                                
byte[] input = new byte[length];                        
ServletInputStream sin = request.getInputStream();      
int c, count = 0;

while((c = sin.read(input, count, input.length-count)) != -1) {
    count = +c;                                          
}                                                           

sin.close();

String receivedString = new String(input);              
response.setStatus(HttpServletResponse.SC_OK);

System.out.print(receivedString);

但是当我运行我的命令并尝试发送字符串时,我在servlet端获得Negative array size exceptionbyte[] input = new byte[length];

Feb 01, 2014 2:06:02 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [project_server.Login] in context with path [/project_server] threw exception
java.lang.NegativeArraySizeException
    at project_server.Login.doPost(Login.java:47)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

我不确定这里有什么问题,但错误意味着它没有收到任何字符串。 LogCat显示应用程序端没有错误。

1 个答案:

答案 0 :(得分:1)

  

我不确定这里有什么问题,但错误意味着它没有收到任何字符串。

不,错误意味着您正在尝试创建一个负长度的数组。这暗示了这些界限:

int length = request.getContentLength();                                
byte[] input = new byte[length];    

可能未设置Content-Length标头,因此getContentLength()返回-1。您应该能够处理 - 只需从输入流中读取,直到read()返回非正数。例如,您可以使用ByteArrayOutputStream复制数据。或者,您可以使用StringBuilder并在输入流周围创建InputStreamReader

char[] buffer = new char[8192];
StringBuilder builder = new StringBuilder();
try (Reader reader = new InputStreamReader(request.getInputStream(), "UTF-8")) {
    int charsRead;
    while ((charsRead = reader.read(buffer)) > 0) {
        builder.append(buffer, 0, charsRead);
    }
}
String text = builder.toString();

请注意我是如何指定UTF-8作为输入编码的 - 在数据时也应该指定相同的编码。目前,您依赖平台默认编码在客户端上与服务器相同,这是一个坏主意。