简体   繁体   English

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

[英]How to send a JSON Object to a web service using HttpURLConnection class in Android?

I have Rest Web Service developed using RESTEasy API, that accepts a Json Object and do some processing. 我有使用RESTEasy API开发的Rest Web Service,该API接受Json Object并进行一些处理。 I have written two clients for this, An Android Client and a normal Java Program Client. 我为此编写了两个客户端,一个Android客户端和一个普通的Java程序客户端。 These two are basically the same doing the same function except the connection making part. 除了连接建立部分外,这两个基本上具有相同的功能。

I'm using the RESTEasy Connection APIs in the Java Client and HttpURLConnection in the Android app since it is the recommended one (Instead of old Apache HttpClient). 我使用Java客户端中的RESTEasy Connection API和Android应用程序中的HttpURLConnection,因为它是推荐的API(而不是旧的Apache HttpClient)。

Everything works fine in the Java Client, but it's not the same for the Android App. Java客户端中的所有功能都可以正常运行,但Android应用程序则不尽相同。 I'm getting this exception "com.fasterxml.jackson.core.jsonparseexception: unexpected end-of-input" when i run the Android client. 当我运行Android客户端时,出现此异常“ com.fasterxml.jackson.core.jsonparseexception:意外的输入结束”。

I didn't understand what was wrong so i tried some debug test using Chrome Advanced Rest Client to check whether everything was okay with the Web Service. 我不明白发生了什么问题,因此我尝试使用Chrome Advanced Rest Client进行了一些调试测试,以检查Web Service是否一切正常。 So i took a copy of the Json String from both clients and executed as a POST request to the web service and it worked perfectly. 因此,我从两个客户端获取了Json String的副本,并将其作为对Web服务的POST请求执行,并且运行良好。

And after doing some more testing i assumed that this was because HttpURLConnection connection use an OutputStream to write the data and it sends a binary stream to the endpoint and the web service couldn't read the web service properly. 在进行了更多测试之后,我认为这是因为HttpURLConnection连接使用OutputStream写入数据,并且它将二进制流发送到端点,并且Web服务无法正确读取Web服务。 That's all i could think of. 这就是我能想到的。 (I tested the Json String with Jasonlint tool and they were all valid.) (我使用Jasonlint工具测试了Json String,它们都是有效的。)

Can somebody explain me what i'm doing wrong or how to do call the web service properly with HttpURLConnection? 有人可以向我解释我在做错什么,或者如何使用HttpURLConnection正确调用Web服务吗? Thanks in Advance. 提前致谢。

Web Service Code 网络服务代码

@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 Client Code (Connection Part) 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();
                  }

Stack Trace of the Error 错误的堆栈跟踪

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,看来您的远程服务器有问题。

Instead of using OutputStreamWriter i used Output Stream and encoded the bytes using UTF-8 charset. 我没有使用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.

相关问题 如何使用HttpURLConnection确定Web服务状态? - How to determine the web service status using HttpURLConnection? 如何使用HttpPost将Json发送到Web服务 - How to send a Json to a web service using HttpPost ANDROID-如何使用httpurlconnection从android中的Web服务获得成功返回? - ANDROID - How to get return success from web service in android using httpurlconnection? android使用HttpURLConnection请求一个php web服务并提交php表单 - android request a php web service using HttpURLConnection and submit the php form ANDROID-使用HttpURLConnection通过json响应将数据发送到API - ANDROID - Send data through json response into API using HttpURLConnection 如何使用HttpURLConnection将序列化对象从Java类发送到Servlet? - How to use HttpURLConnection to send serialized object to a Servlet from Java class? 如何使用HttpURLConnection在Java Web服务中执行身份验证 - How to perform authentication in a java web service using HttpURLConnection 如何使用HTTPURLConnection和JSON数据发送POST请求 - How to send POST request using HTTPURLConnection with JSON data 如何使用 HttpUrlConnection 发送 JSON 和附件 - How to send both JSON and an attached file using HttpUrlConnection 如何使用 HttpURLConnection 将 GET 请求与 Web API 一起用于 JSON 响应? - How use GET request with web API for JSON response using HttpURLConnection?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM