[英]Parsing JSON data sent by an Android application
hmkcode.com发布的应用程序从用户那里获取一些数据并进行解析和转换 ,然后发送到名为jsonservlet的Java servlet。 我更改了解析的输入值,但每次都收到NullPointerException
。
java.lang.NullPointerException
java.io.StringReader.<init>(StringReader.java:50)
com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:796)
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
iaau.uimsmobile.getData.getDataServlet.doPost(getDataServlet.java:48)
iaau.uimsmobile.getData.getDataServlet.doGet(getDataServlet.java:65)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
LogCat跟踪
02-01 10:31:38.232 424-424/com.iaaum D/dalvikvm﹕ GC_EXTERNAL_ALLOC freed 81K, 52% free 2630K/5379K, external 904K/1038K, paused 72ms
02-01 10:32:03.392 424-424/com.iaaum W/KeyCharacterMap﹕ No keyboard for id 0
02-01 10:32:03.392 424-424/com.iaaum W/KeyCharacterMap﹕ Using default keymap: /system/usr/keychars/qwerty.kcm.bin
02-01 10:32:08.962 424-433/com.iaaum D/InputStream﹕ Connection to http://localhost:8080 refused
02-01 10:34:28.142 424-434/com.iaaum D/InputStream﹕ Connection to http://localhost:8080 refused
最后,我在两侧的toString()
方法中更改了JSON格式的字符串。 @SotiriosDelimanolis谈论的失败出现了 。
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
at [Source: java.io.StringReader@30b3b5; line: 1, column: 1]
com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:2931)
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2873)
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
iaau.uimsmobile.getData.getDataServlet.doPost(getDataServlet.java:48)
iaau.uimsmobile.getData.getDataServlet.doGet(getDataServlet.java:65)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
客户端-> User.java
public class User{
private String IDnumber;
private String Password;
public String getIDnumber() {
return IDnumber;
}
public void setIDnumber(String IDnumber) {
this.IDnumber = IDnumber;
}
public String getPassword() {
return Password;
}
public void setPassword(String password) {
Password = password;
}
@Override
public String toString()
{
// { "IDnumber":"" , "Password":"" }
return "{\"IDnumber\":"+"\""+IDnumber+"\""+",\"Password\":"+"\""+Password+"\"}";
}
}
客户端-> LoginActivity.java
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.Toast;
import com.iaaum.user.User;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class LoginActivity extends Activity implements OnClickListener
{
TextView IsConnected;
EditText id_number;
EditText password;
Button sign_button;
User current_user;
public String urlAddress = "http://192.168.1.101:8080/UIMSMobile/getDataServlet";
//public String urlAddress = "http://127.0.0.1:8080/UIMSMobile/getDataServlet";
//public String urlAddress = "http://localhost:8080/UIMSMobile/getDataServlet";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_login);
// get reference to the views
IsConnected = (TextView) findViewById(R.id.isConnected);
id_number = (EditText) findViewById(R.id.id_number);
password = (EditText) findViewById(R.id.password);
sign_button= (Button) findViewById(R.id.sign_in_button);
// check if you are connected or not
if(IsConnectedMethod())
{
IsConnected.setBackgroundColor(0xFF00CC00);
IsConnected.setText("You are connected");
}
else{
IsConnected.setText("You are NOT connected");
}
// add click listener to Button "POST"
sign_button.setOnClickListener(this);
}
@Override
public void onClick(View view)
{
switch(view.getId()){
case R.id.sign_in_button:
if(!validate())
Toast.makeText(getBaseContext(), "Enter some data!", Toast.LENGTH_LONG).show();
// call AsyncTask to perform network operation on separate thread
new HttpAsyncTask().execute(urlAddress);
break;
}
}
public boolean IsConnectedMethod()
{
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
public static String Post(String url, User current_user)
{
InputStream inputStream = null;
String result = "";
try
{
// 1. create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost(url);
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("IDnumber", current_user.getIDnumber());
jsonObject.accumulate("Password", current_user.getPassword());
// 4. convert JSONObject to JSON in String
json = jsonObject.toString();
// ** Alternative way to convert Person object to JSON string using Jackson Lib
// ObjectMapper mapper = new ObjectMapper();
// json = mapper.writeValueAsString(person);
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
// 9. receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// 10. convert inputstream to string
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
// 11. return result
return result;
}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls)
{
current_user = new User();
current_user.setIDnumber(id_number.getText().toString());
current_user.setPassword(password.getText().toString());
return Post(urls[0], current_user);
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), "Data Sent!", Toast.LENGTH_LONG).show();
}
}
private boolean validate()
{
if(id_number.getText().toString().trim().equals(""))
return false;
else return !password.getText().toString().trim().equals("");
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException {
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
}
客户端-> AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iaaum" >
<uses-sdk
android:minSdkVersion="8"
android:maxSdkVersion="19"
/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.iaaum.LoginActivity"
android:label="@string/title_activity_login" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
服务器端-> User.java
public class User
{
private String idnumber;
private String password;
public User(String idnumber, String password) {
this.idnumber = idnumber;
this.password = password;
}
public String getIDnumber() {
return idnumber;
}
public void setIDnumber(String idnumber) {
this.idnumber = idnumber;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString()
{
return "{\"IDnumber\":"+"\""+idnumber+"\""+",\"Password\":"+"\""+password+"\"}";
}
}
服务器端-> getDataServlet.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
public class getDataServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
// This will store all received articles
List<User> _users = new LinkedList<User>();
/***************************************************
* URL: /getDataServlet
* doPost(): receives JSON data, parse it, map it and send back as JSON
* @param request
* @param response
* @throws javax.servlet.ServletException
* @throws java.io.IOException
****************************************************/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// 1. get received JSON data from request
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String json = "";
if(br.readLine() != null)
{
json = br.readLine();
}
// 2. initiate jackson mapper
ObjectMapper mapper = new ObjectMapper();
// 3. Convert received JSON to User
User _user = mapper.readValue(json, User.class);
// 4. Set response type to JSON
response.setContentType("application/json");
// 5. Add article to List<Article>
_users.add(_user);
// 6. Send List<Article> as JSON to client
mapper.writeValue(response.getOutputStream(), _users);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
@Override
public String getServletInfo()
{
return "Short description";
}
}
引发异常的唯一方法是,如果传入的String
json
mapper.readValue(json, User.class);
为null
。
您在这里做错了
if(br != null)
{
json = br.readLine();
}
br
在那里永远不可能为null
。 也许你是说
String temp;
if ((temp = br.readLine()) != null)
{
json = temp;
}
甚至更好的方法是,将流直接传递到ObjectMapper
的重载readValue(..)
方法之一,并处理所有错误。
无论如何,似乎您都没有在请求的正文中发送任何内容,因此readLine()
返回您分配给json
null
,这会导致ObjectMapper
的失败。
您的doGet()
委托给您的doPost()
。 您是否正在发送GET请求?
通过处理您的建议,我对代码进行了一些更改,该应用程序现在可以正常工作。 更改如下:
服务器端---> getDataServlet.java
package com.****;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.****.dao.User;
public class getDataServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
List<User> users = new LinkedList<User>();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String json = "";
if(br != null){
json = br.readLine();}
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
response.setContentType("application/json");
if(users.size() > 20){
users.remove(0);}
users.add(user);
mapper.writeValue(response.getOutputStream(), users);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
ObjectMapper mapper = new ObjectMapper();
resp.setContentType("application/json");
mapper.writeValue(resp.getOutputStream(), users);
}
}
服务器端-> User.java
package com.*****.dao;
public class User {
private String idnumber;
private String password;
public String getIdnumber() {
return idnumber;
}
public void setIdnumber(String idnumber) {
this.idnumber = idnumber;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [idnumber=" + idnumber + ", password=" + password + "]";
}
}
客户端---> MainActivity.java
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("idnumber", user.getIdnumber());
jsonObject.accumulate("password", user.getPassword());
客户端---> User.java
@Override
public String toString()
{
return "User [idnumber=" + idnumber + ", password=" + password + "]";
}
并且在发布数据输出出现之后:
[{“ idnumber”:“ 987654321”,“ password”:“ 123456789”}]
可能是您给定URL的问题,如果您在localhost
工作,则使用IP Address
而不是localhost
ipconfig
命令在命令提示符下检查IP。 在您的User.java
您可能必须使用JSONObject
和JSONArray
在toString()
方法中创建JSON字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.