Unable to send a string from app to servlet using outputStreamWriter()

I'm trying to send a small String over from my app to a 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();

The servlet is supposed to receive the value through 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);

But when I run my command and try to send the String over, I get Negative array size exception on the servlet side for the line byte[] 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)

I'm not sure what is wrong here but the error implies that it is not receiving any string. LogCat shows no error for the app side.

Jon Skeet
people
quotationmark

I'm not sure what is wrong here but the error implies that it is not receiving any string.

No, the error implies that you're trying to create an array with a negative length. That implicates these lines:

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

Presumably the Content-Length header isn't being set, so getContentLength() is returning -1. You should be able to handle that - just read from the input stream until read() returns a non-positive number. For example, you can copy the data using a ByteArrayOutputStream. Alternatively, you could just use a StringBuilder and create an InputStreamReader around the input stream:

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

Note how I've specified UTF-8 as the input encoding - you should specify the same encoding when writing the data too. At the moment you're relying on the platform default encoding being the same on the client as the server, which is a bad idea.

people

See more on this question at Stackoverflow