[英]How to send a JSON Object to a web service using HttpURLConnection class in Android?
我有使用RESTEasy API开发的Rest Web Service,该API接受Json Object并进行一些处理。 我为此编写了两个客户端,一个Android客户端和一个普通的Java程序客户端。 除了连接建立部分外,这两个基本上具有相同的功能。
我使用Java客户端中的RESTEasy Connection API和Android应用程序中的HttpURLConnection,因为它是推荐的API(而不是旧的Apache HttpClient)。
Java客户端中的所有功能都可以正常运行,但Android应用程序则不尽相同。 当我运行Android客户端时,出现此异常“ com.fasterxml.jackson.core.jsonparseexception:意外的输入结束”。
我不明白发生了什么问题,因此我尝试使用Chrome Advanced Rest Client进行了一些调试测试,以检查Web Service是否一切正常。 因此,我从两个客户端获取了Json String的副本,并将其作为对Web服务的POST请求执行,并且运行良好。
在进行了更多测试之后,我认为这是因为HttpURLConnection连接使用OutputStream写入数据,并且它将二进制流发送到端点,并且Web服务无法正确读取Web服务。 这就是我能想到的。 (我使用Jasonlint工具测试了Json String,它们都是有效的。)
有人可以向我解释我在做错什么,或者如何使用HttpURLConnection正确调用Web服务吗? 提前致谢。
网络服务代码
@Path("/upload")
public class ImageTransferHandler {
@POST
@Path("/jsonString")
@Consumes("application/json")
public Response upload (ImageData jsonString){
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Image.class, new ImageDeserializer());
Gson gson = builder.create();
//Image image = gson.fromJson(jsonString, Image.class);
ImageData image = jsonString;
System.out.println("sys out : Name: " + image.getImageName() + " \nEncoded Image String : " + image.getEncodedImageString());
// Decode the base64 String and get the byte array
byte[] imageBytes = image.getEncodedImageString().getBytes();
byte[] decodedBytes = Base64.decodeBase64(imageBytes);
try {
// Convert the bytes to an image and store
ImageConverter ic = new ImageConverter();
ic.bytesToImage(decodedBytes, "C:\\Users\\yomal.ds\\Desktop\\test\\output.jpg");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
/**
* Checksum Code Start
* */
MessageDigest md1 = MessageDigest.getInstance("SHA-256");
md1.update(imageBytes);
byte[] mdbytes1 = md1.digest();
StringBuffer hexedHashB64 = new StringBuffer();
for (int i = 0; i < mdbytes1.length; i++) {
hexedHashB64.append(Integer.toString((mdbytes1[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("HEXED HASH (Base64) : " + hexedHashB64.toString());
/**
* Checksum Code End
* */
/**
* Checksum Code Start
* */
MessageDigest md2 = MessageDigest.getInstance("SHA-256");
md2.update(decodedBytes);
byte[] mdbytes2 = md2.digest();
StringBuffer hexedHash = new StringBuffer();
for (int i = 0; i < mdbytes2.length; i++) {
hexedHash.append(Integer.toString((mdbytes2[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("HEXED HASH (Original) : " + hexedHash.toString());
/**
* Checksum Code End
* */
} catch (NoSuchAlgorithmException e) {
System.err.println("Algorithm is not correct");
e.printStackTrace();
}
return Response.status(200).entity(image.toString()).build();
}
}
Android客户端代码(连接部分)
try {
Log.e("Upload", "Making connection");
String url= "http://192.168.43.2:8080/RestEasyWS/rest/upload/jsonString";
URL urlObj = new URL(url);
Log.e("Upload", "Opening tunnel");
HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
Log.e("Upload", "Tunnel Opened");
con.setDoInput(true);
con.setDoOutput(true);
con.setChunkedStreamingMode(0);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Accept-Encoding","gzip, deflate");
con.setRequestProperty("Accept-Language","en-US,en;q=0.8");
con.setRequestMethod("POST");
Log.e("Upload", "Connection Made");
OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream());
Log.e("Upload", "Uploading...");
osw.write(jsonString);
Log.e("Upload", "Uploaded...");
Log.e("Upload", "Server Response : " + con.getResponseCode() + " - " + con.getResponseMessage() );
osw.flush();
osw.close();
} catch (IOException e) {
Log.e("Connection", "Error In Opening a Connection");
e.printStackTrace();
}
错误的堆栈跟踪
Mar 16, 2016 12:16:00 PM org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher processApplication
INFO: RESTEASY002225: Deploying javax.ws.rs.core.Application: class com.informatics.webservice.MessageApplication
Mar 16, 2016 12:16:00 PM org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher processApplication
INFO: RESTEASY002220: Adding singleton resource com.informatics.webservice.imagetransfer.ImageTransferHandler from Application class com.informatics.webservice.MessageApplication
Mar 16, 2016 12:16:04 PM org.jboss.resteasy.core.ExceptionHandler handleFailure
ERROR: RESTEASY002005: Failed executing POST /upload/jsonString
org.jboss.resteasy.spi.ReaderException: com.fasterxml.jackson.databind.JsonMappingException: Unexpected end-of-input in VALUE_STRING
at [Source: org.apache.catalina.connector.CoyoteInputStream@9ceeccd; line: 1, column: 7236430]
at [Source: org.apache.catalina.connector.CoyoteInputStream@9ceeccd; line: 1, column: 23] (through reference chain: com.informatics.webservice.commonobjects.ImageData["encodedImageString"])
at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:184)
at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:91)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:114)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:395)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:202)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unexpected end-of-input in VALUE_STRING
at [Source: org.apache.catalina.connector.CoyoteInputStream@9ceeccd; line: 1, column: 7236430]
at [Source: org.apache.catalina.connector.CoyoteInputStream@9ceeccd; line: 1, column: 23] (through reference chain: com.informatics.webservice.commonobjects.ImageData["encodedImageString"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:339)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:299)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1511)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:262)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1534)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:944)
at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.readFrom(ResteasyJackson2Provider.java:121)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.readFrom(AbstractReaderInterceptorContext.java:61)
at org.jboss.resteasy.core.interception.ServerReaderInterceptorContext.readFrom(ServerReaderInterceptorContext.java:60)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:53)
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.aroundReadFrom(GZIPDecodingInterceptor.java:59)
at org.jboss.resteasy.core.interception.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:55)
at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:151)
... 30 more
您是否在其他客户端(邮递员)上测试过api,看来您的远程服务器有问题。
我没有使用OutputStreamWriter,而是使用Output Stream并使用UTF-8字符集对字节进行编码。
OutputStream os= con.getOutputStream();
os.write(jsonString.getBytes("UTF-8"));
os.flush;
os.close;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.