如何使用Android中的HttpURLConnection类将JSON对象发送到Web服务?

时间:2016-03-16 11:06:46

标签: java android web-services resteasy

我使用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

2 个答案:

答案 0 :(得分:0)

你有没有在休息客户端上测试api(发帖人),这似乎是你的远程服务器问题。

答案 1 :(得分:0)

我没有使用OutputStreamWriter,而是使用了输出流,并使用UTF-8字符集对字节进行了编码。

OutputStream os= con.getOutputStream();
os.write(jsonString.getBytes("UTF-8"));
os.flush;
os.close;