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.
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.
See more on this question at Stackoverflow