繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM