简体   繁体   English

解析Android应用程序发送的JSON数据

[英]Parsing JSON data sent by an Android application

The application published by hmkcode.com takes some data from user and parse & convert , and send to a java servlet called jsonservlet . hmkcode.com发布的应用程序从用户那里获取一些数据并进行解析转换 ,然后发送到名为jsonservlet的Java servlet。 I changed the input values parsed but I'm receiving everytime NullPointerException . 我更改了解析的输入值,但每次都收到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 trace 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

At last, I changed the strings in JSON format inside the toString() methods in both sides. 最后,我在两侧的toString()方法中更改了JSON格式的字符串。 The failure what @SotiriosDelimanolis talked about is appeared . @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)

Client side --> User.java 客户端-> 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+"\"}";
}
}

Client side --> LoginActivity.java 客户端-> 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;
    }

}

Client side --> AndroidManifest.xml 客户端-> 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>

Server side --> User.java 服务器端-> 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+"\"}";
    }        
}

Server side --> getDataServlet.java 服务器端-> 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";
    }

}

The only way that exception could be thrown is if the String json you pass in 引发异常的唯一方法是,如果传入的String json

mapper.readValue(json, User.class);

is null . null

You're doing something wrong here 您在这里做错了

if(br != null)
{
    json = br.readLine();
}

br could never be null there. br在那里永远不可能为null Maybe you meant 也许你是说

String temp;
if ((temp = br.readLine()) != null)
{
    json = temp;
}

Or even better, pass the stream directly to one of the ObjectMapper 's overloaded readValue(..) methods and handle any errors. 甚至更好的方法是,将流直接传递到ObjectMapper的重载readValue(..)方法之一,并处理所有错误。

In any case, it seems you aren't sending anything in the body of the request, so readLine() returns null which you assign to json and that causes a failure in the ObjectMapper . 无论如何,似乎您都没有在请求的正文中发送任何内容,因此readLine()返回您分配给json null ,这会导致ObjectMapper的失败。

Your doGet() is delegating to your doPost() . 您的doGet()委托给您的doPost() Is it possible you are sending GET requests? 您是否正在发送GET请求?

By handling your suggessions, I made some changes in codes and the application is working now. 通过处理您的建议,我对代码进行了一些更改,该应用程序现在可以正常工作。 Here is the changes: 更改如下:

Server Side ---> getDataServlet.java 服务器端---> 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);
    }
}

Server Side --> User.java 服务器端-> 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  + "]";
    }
}

Client Side ---> MainActivity.java 客户端---> MainActivity.java

JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("idnumber", user.getIdnumber());
jsonObject.accumulate("password", user.getPassword());

Client Side ---> User.java 客户端---> User.java

@Override
public String toString() 
{
    return "User [idnumber=" + idnumber + ", password=" + password + "]";
}

And after post data output appeared: 并且在发布数据输出出现之后:

[{"idnumber":"987654321 ","password":"123456789"}] [{“ idnumber”:“ 987654321”,“ password”:“ 123456789”}]

Solution 1: 解决方案1:

May be its problem of you given URL, if you working on localhost then use your IP Address instead of localhost 可能是您给定URL的问题,如果您在localhost工作,则使用IP Address而不是localhost

you can check your IP in command prompt using ipconfig command. 您可以使用ipconfig命令在命令提示符下检查IP。

Solution 2: 解决方案2:

In your User.java You may have to use JSONObject and JSONArray to create JSON String in toString() method. 在您的User.java您可能必须使用JSONObjectJSONArraytoString()方法中创建JSON字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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