gpt4 book ai didi

java - 异步任务与 Java Servlet 的消息交换

转载 作者:行者123 更新时间:2023-12-02 04:51:27 25 4
gpt4 key购买 nike

我有一个简单的应用程序通过异步任务与其 Servlet 后端进行通信。我在理解消息如何包装以及如何操作这些消息的数据结构方面遇到一些困难。我想做的是接收多个对象或多个异构信息。我的代码:

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:

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

但是,我想要的是将其按原样存储为 ArrayList。如何配置异步任务以接收 m_tours ArrayList 并将其存储在某处以供进一步使用?此外,如何配置它来接收多个对象?

* 编辑*

我尝试按照@orip的建议使用Gson,设置异步任务如下:

@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);
}

}

但我收到错误:

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));

我做错了什么?

* 编辑2 *已解决:

错误:引起:com.google.gson.stream.MalformedJsonException:使用 JsonReader.setLenient(true) 接受格式错误的 JSON 是由于我正在调用 resp .getWriter().print() 两次,按照@orip的建议。谢谢你!

最佳答案

将 servlet 的内容类型设置为 application/json 并返回 JSON 字符串(例如使用 Gson 或 Jackson 来序列化结果。

在 Android 端,您可以使用 Android 的内置 JSON 类或(更好)使用您在 servlet 中使用的相同库来反序列化 JSON 字符串。

例如,如果 Tour 类似于:

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

您可以构建一个响应类,例如:

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

然后在服务器端(请参阅 this question ,我在这里使用 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,您最终可能会得到更简单、更健壮的代码。

关于java - 异步任务与 Java Servlet 的消息交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29197515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com