异步任务的消息与的Java Servlet交流 [英] Async task's messages exchange with Java Servlet

查看:288
本文介绍了异步任务的消息与的Java Servlet交流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有过一个异步任务,其后台的Servlet一个简单的应用程序进行通信。 我有一些很难理解如何将邮件包裹起来,以及如何处理这些消息的数据结构。 我想要做的是接受或多个对象,或多个异构的信息呢。 我的code:

I have a simple app communicating with its Servlet backend through an Async task. I have some trouble understanding how the messages are wrapped up and how to manipulate the data structures of these messages. What I want to do is to receive either multiple objects, or multiple heterogeneous information anyway. My code:

public class MyServlet extends HttpServlet {
    ArrayList<Tour> m_tours;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException {
    resp.setContentType("text/plain");
    resp.getWriter().println("Please use the form to POST to this url");

    }

    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

    String order = req.getParameter("order");
    resp.setContentType("text/plain");
    if (order == null) {
        resp.getWriter().println("Please enter a name");
    }

      resp.getWriter().println("yay name received");
      ArrayList<Tour> m_tours = getTours(); //returns a populated ArrayList of custom Tour objects
      resp.getWriter().print(m_tours);
}
    private void getTours(){
        //some code here
    }
}`

和我的异步任务等级:

class ServletPostAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
private Context context;
@Override
protected String doInBackground(Pair<Context, String>... params) {
    context = params[0].first;
    String order = params[0].second;

    String[] url = new String[3];
    url[0] = "http://192.168.169.85:8080/hello";
    url[1] = "http://10.0.2.2:8080/hello";
    url[2] = "http://192.168.1.102:8080/hello";
    HttpClient httpClient = new DefaultHttpClient(); 
    HttpPost httpPost = new HttpPost(url[2]);

    List<NameValuePair> nameValuePairs = new ArrayList<>(1);
    nameValuePairs.add(new BasicNameValuePair("order", order));
        try {
            // Add name data to request
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            // Execute HTTP Post Request
            HttpResponse response = httpClient.execute(httpPost);

            HttpEntity entity = response.getEntity();
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(entity);
            }
                return "Error: " + response
                        .getStatusLine()
                        .getStatusCode() + " " + response
                        .getStatusLine().getReasonPhrase();
        } catch (ClientProtocolException e) {
            return e.getMessage();
        } catch (IOException e) {
            return e.getMessage();
        }
    }

@Override
protected void onPostExecute(String result) {
       String result1 = "Response: "+result;
           Toast.makeText(context, result1, Toast.LENGTH_LONG).show();
    }
}

响应消息返回的ArrayList文本:

The response message returns ArrayList as text:

 Response: yay name received
 packagename@objectkey1
 packagename@objectkey2
 packagename@objectkey3
 ...
 packagename@objectkeyn

但是,相反,我要的是保存它,因为它是作为一个ArrayList。 我该如何配置我的异步任务领取我的m_tours ArrayList和存储在某个地方作进一步使用? 此外,如何配置它来接收多个对象?

But instead, what I want is to store it as it is, as an ArrayList. How can I configure my Async task to receive my m_tours ArrayList and store it somewhere for further use? Furthermore, how can I configure it to receive multiple objects?

*编辑*

我已经用GSON尝试所建议的@orip,设置异步任务如下:

I've tried by using Gson as suggested by @orip, setting the Async task as follows:

@Override
protected String doInBackground(Pair<Context, String>... params) {
    context = params[0].first;
    String order = params[0].second;

    String[] url = new String[3];
    url[0] = "http://192.168.169.85:8080/hello";
    url[1] = "http://10.0.2.2:8080/hello";
    url[2] = "http://192.168.1.102:8080/hello";
    // HttpPost httpPost = new HttpPost("http://semiotic-art-88319.appspot.com/hello");
    HttpClient httpClient = new DefaultHttpClient(); //127.0.0.1 - 10.201.19.153
    HttpPost httpPost = new HttpPost(url[2]);

    List<NameValuePair> nameValuePairs = new ArrayList<>(1);
    nameValuePairs.add(new BasicNameValuePair("order", order));

    try {
        // Add name data to request
        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        // Execute HTTP Post Request
        HttpResponse response = httpClient.execute(httpPost);
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        }
        return "Error: " + response
                .getStatusLine()
                .getStatusCode() + " " + response
                .getStatusLine().getReasonPhrase();
    } catch (ClientProtocolException e) {
        return e.getMessage();
    } catch (IOException e) {
        return e.getMessage();
    }
}

@Override
protected void onPostExecute(String jsonResponse) {
    Gson gson = new Gson();
    tours = (gson.fromJson(jsonResponse, Tours.class));
    Toast.makeText(context, jsonResponse, Toast.LENGTH_LONG).show();
}

和服务器端的:

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

    String asyncMessage = req.getParameter("order");
    if(asyncMessage.equals("tours")){
        m_tours = getTours();  //ArrayList<Tour> m_tours;
        Tours tours = new Tours(m_tours);
        resp.setContentType("application/json");
        PrintWriter out = resp.getWriter();
        out.print(new Gson().toJson(tours));
        out.flush();

        resp.getWriter().print(m_tours);
    }

}

但我得到一个错误:

but I get an error:

03-23 13:27:09.523  32387-32387/madapps.bicitourbo E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: madapps.bicitourbo, PID: 32387
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 692 path $
        at com.google.gson.Gson.assertFullConsumption(Gson.java:786)
        at com.google.gson.Gson.fromJson(Gson.java:776)
        at com.google.gson.Gson.fromJson(Gson.java:724)
        at com.google.gson.Gson.fromJson(Gson.java:696)
        at madapps.bicitourbo.ServletPostAsyncTask.onPostExecute(ServletPostAsyncTask.java:92)
        at madapps.bicitourbo.ServletPostAsyncTask.onPostExecute(ServletPostAsyncTask.java:36)
        at android.os.AsyncTask.finish(AsyncTask.java:632)
        at android.os.AsyncTask.access$600(AsyncTask.java:177)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:149)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 692 path $

此错误就行发生:

Tour tours = (gson.fromJson(jsonResponse, Tours.class));

我该怎么办错了?

What do I do wrong?

* EDIT2 * 解决:

错误:致:com.google.gson.stream.MalformedJsonException:使用JsonReader.setLenient(真)接受畸形的JSON 是由于这样的事实,我在呼唤 resp.getWriter()的print()的两倍,所建议的@orip。谢谢!

The error: Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON was due to the fact that I was calling resp.getWriter().print() two times, as suggested by @orip. Thank you!

推荐答案

设置servlet的内容类型为应用程序/ JSON ,并返回一个JSON字符串(例如,使用GSON或杰克逊序列化的结果。

Set the servlet's content type to application/json and return a JSON string (e.g using Gson or Jackson to serialize the result.

在Android的一面,你可以反序列化的JSON字符串,或者使用Android的内置JSON类或(最好)使用您在你的servlet中使用的相同的库。

On the Android side you can deserialize the JSON string, either using Android's built-in JSON classes or (better) using the same libraries you used in your servlet.

例如,如果旅游是这样的:

public class Tour {
  // some simple int/string/list fields
}

您可以建立一个响应等级,如:

You can build a response class like:

public class Tours {
  private List<Tour> tours;
  // ...
}

然后在服务器端(见<一href="http://stackoverflow.com/questions/2010990/how-do-you-return-a-json-object-from-a-java-servlet">this问题,我使用 GSON 这里):

List<Tour> listOfTours = ...;
Tours tours = new Tours(listOfTours);
response.setContentType("application/json");
PrintWriter out = response.getWriter();
out.print((new Gson()).toJson(tours));
out.flush();

和在客户端:

String jsonResponse = ...;
Tours tours = (new Gson()).fromJson(jsonResponse, Tours.class);

有一些优化来进行,但可能让你开始。 另外,可以考虑使用 OkHttp 进行HTTP连接,而不是使用的HttpClient ,你可能会结束了更简单,更强大的code。

There are some optimizations to be made, but that could get you started. Also, consider using OkHttp for your HTTP connections instead of using HttpClient, you'll probably end up with simpler and more robust code.

这篇关于异步任务的消息与的Java Servlet交流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆