我使用RESTEasy API开发Rest Web Service,它接受Json对象并进行一些处理。我为此编写了两个客户端,一个Android客户端和一个普通的Java程序客户端。除连接制作部分外,这两个基本相同,功能相同。
我在Android应用程序中使用RESTEasy Connection API,在Android应用程序中使用HttpURLConnection,因为它是推荐的(而不是旧的Apache HttpClient)。
Java Client中的一切正常,但对于Android App来说却不一样。我得到了这个异常" com.fasterxml.jackson.core.jsonparseexception:意外的输入结束"当我运行Android客户端时。
我没有理解错误,所以我尝试使用Chrome Advanced Rest Client进行一些调试,以检查Web服务是否一切正常。所以我从两个客户端获取了一个Json String的副本,并作为POST请求执行到Web服务,并且它运行良好。
在做了一些测试之后,我认为这是因为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
答案 0 :(得分:0)
你有没有在休息客户端上测试api(发帖人),这似乎是你的远程服务器问题。
答案 1 :(得分:0)
我没有使用OutputStreamWriter,而是使用了输出流,并使用UTF-8字符集对字节进行了编码。
OutputStream os= con.getOutputStream();
os.write(jsonString.getBytes("UTF-8"));
os.flush;
os.close;