从 android 应用程序到动态 Web servlet 的通信

Posted

技术标签:

【中文标题】从 android 应用程序到动态 Web servlet 的通信【英文标题】:communicatin from android app to dynamic web servlet 【发布时间】:2014-03-14 06:25:48 【问题描述】:

您好,我正在尝试在模拟器上运行一个简单的应用程序,该应用程序将使用(http://10.0.2.2:8080/...)作为连接到的 IP 将数据发送到在同一台 PC 上运行的 servlet主机

补充阅读:这是一个 princable 测试,有望让我在手机上运行应用程序并连接到在家中运行的 servlet,最终将用于连接到 mysql 数据库。 我有一些代码似乎可以满足我的要求,但我不确定它是否符合规定,或者我是否正确实现了它

/** 安卓端 **/

import java.io.DataOutputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView;
import android.widget.Toast;

/**adapted code from online**/
public class Test extends Activity  
     static final String TAG = "Test"; 
    // Called when the activity is first created.  

    protected static EditText username; 
    protected static EditText password;
    TextView tview;
    String uname ="";

    @Override 
    public void onCreate(Bundle icicle)  
        super.onCreate(icicle); 
        setContentView(R.layout.testlogin); 

        username = (EditText)findViewById(R.id.username); 
        password = (EditText)findViewById(R.id.password);
        tview = (TextView)findViewById(R.id.view);
        Toast.makeText(this, "started",1).show();
        tview.append("\nstarted\n"); 
     

    public void login(View v)  //in testlogin.xml//android:onClick="login"
        Toast.makeText(this, "button pressed",1).show();
        Log.v(TAG, "button pressed");
        //tview.append("clicked\n");
        uname=username.getText().toString(); 
        networkthread ob = new networkthread(uname); 
     


class networkthread implements Runnable  
        private static final String TAG = "Test"; 
        String uname; 
        public networkthread(String uname)  
                this.uname =  uname; 
                Thread t = new Thread(this); 
                t.start(); 
         
        public void run()


                Log.v(TAG, "inside sub thread"); 

                try  
                    URL ob = new URL("http://10.0.2.2:8080/Server/test"); 
                    URLConnection           conn = ob.openConnection(); 
                    conn.setDoInput(true); 
                    conn.setDoOutput(true); 
                    OutputStream out = conn.getOutputStream(); 
                    DataOutputStream dos =  new DataOutputStream(out); 
                    dos.writeInt(uname.getBytes().length); 
                    dos.write(uname.getBytes(),0,uname.getBytes().length); 
                    dos.flush(); 
                    dos.close(); 
                    conn = null; 
                catch(Exception e) 
                        Log.v(TAG, "Exception:" +e); 
                        e.printStackTrace(); 
                 
         
 

/** Dynamic web 项目中的 Servlet 端 **/

import java.io.*; 
import java.net.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class test extends HttpServlet  
    private InputStream is = null; 
    private OutputStream os = null; 
    private DataInputStream dis = null; 
    private DataOutputStream dos = null; 
    boolean isValid = false; 

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException  
        try 
            is = request.getInputStream(); 
            dis = new DataInputStream(is); 
            int  len = dis.readInt(); 
            byte data[] = new byte[len]; 
            dis.read(data,0,len); 
            String userName = new String(data); 
            System.out.println("username:" +userName); 
            is.close(); dis.close(); 
         catch(Exception e) 
            System.out.println(e); 
         
     

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException  
        processRequest(request, response); 
     


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException  
        processRequest(request, response); 
     


    public String getServletInfo()  
        return "Short description"; 
     


我对 android 和 servlet 都有一些经验 当我运行它时没有错误,但消息没有在 servlet 端恢复。我想我可能与应用程序没有等待来自 servlet 的响应或 servlet 没有在应用程序请求连接或类似的东西的同时运行有关

是否有明显的原因导致它无法正常工作,我该如何解决这个问题,以便我可以继续使用手机上的测试应用程序连接到 servlet 任何帮助将不胜感激,我希望在我解决问题之前积极参与这篇文章

【问题讨论】:

当您尝试连接到 url 时,您的 android 应用程序是否出现异常? 感谢您的回复,但我决定使用 JSON 将数据发送到 servlet 而不是流,它可以工作。我可以把我的代码作为答案吗? 【参考方案1】:

应用程序

package com.test;

import java.io.BufferedReader;
import java.io.DataOutputStream; 
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream; 
import java.net.HttpURLConnection;
import java.net.URL; 
import java.net.URLConnection; 


import java.util.HashMap;
import java.util.logging.Logger;

import javax.net.ssl.HttpsURLConnection;

import org.apache.http.Header;
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.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity; 
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.AsyncTask;
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu;
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView;
import android.widget.Toast;


public class Test extends Activity  
    static final String TAG = "Test"; 
    // Called when the activity is first created.  

    protected static EditText username; 
    protected static EditText password;
    TextView tview;
    String uname ="";
    JSONObject json;
    URL url;

    @Override 
    public void onCreate(Bundle icicle)  
        super.onCreate(icicle); 
        setContentView(R.layout.testlogin); 

        username = (EditText)findViewById(R.id.username); 
        password = (EditText)findViewById(R.id.password);
        tview = (TextView)findViewById(R.id.view);
        Toast.makeText(this, "Started",1).show();
        Log.v(TAG,"\nStarted\n"); 
     

    public void login(View v)  //in testlogin.xml//android:onClick="login"
        Toast.makeText(this, "button pressed",1).show();
        Log.v(TAG, "button pressed");
        //tview.append("clicked\n");

        HashMap<String, String> hasmap=new HashMap<String, String>();
        hasmap.put("user",username.getText().toString());
        hasmap.put("pass",password.getText().toString());
        json = new JSONObject(hasmap);
        String sJSON = json.toString();
        new toServlet().execute(sJSON);//sends the jsonString to a aSync task
    

    private class toServlet extends AsyncTask<String, Void, String> 
        @Override

        protected String doInBackground(String... urls) 

            // params comes from the execute() call: params[0] is the url.
            try 
                Log.v(TAG,"In background");
                return connection(urls[0]);//could send message to multible uls
             catch (IOException e) 
                Log.v(TAG,"Error: "+e);
                return "Unable to retrieve web page. URL may be invalid.";
            
        
    
    private String connection (String sJSON)throws IOException//creates new connection each time
        Log.v(TAG, "Connection");
        Log.v(TAG,"In connection "+sJSON);
        URL url;
        InputStream is = null;
        HttpURLConnection conServlet;

        url = new URL("http://10.0.2.2:8080/CheckmateServerSuport/servlet?TAG="+sJSON);
        conServlet = (HttpURLConnection) url.openConnection();
        conServlet.setDoInput(true);
        //con.setDoInput(true);
        conServlet.setRequestMethod("POST");//can be get

        conServlet.connect();//makes the connection and send


        //Response
        is = conServlet.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        Log.v(TAG,"Sent String ");

        String back = br.readLine();
        Log.v(TAG,""+back);

        return back;

    
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    

小服务程序

package com.coreservlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.AbstractDocument.BranchElement;

import org.json.JSONException;
import org.json.JSONObject;

@WebServlet("/servlet")
public class JSONServlet extends HttpServlet

    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException 

        String user ="";
        String pass = "";

        System.out.println("In do Get");
        response.setContentType("application/json");

        try 
            JSONObject jsonRequest = new JSONObject(request.getParameter("TAG"));//from url in app
            System.out.println(jsonRequest);
            user = jsonRequest.getString("user");
            pass = jsonRequest.getString("pass");

            System.out.println("UserName: "+user+" Password: "+pass);

            //send back to app
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("ok","ok");

            JSONObject replyJSON = new JSONObject(map);

            PrintWriter printW = response.getWriter();
            printW.println(replyJSON);

         catch (JSONException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException //essentioall dummy
        doGet(request, response);
    

【讨论】:

以上是关于从 android 应用程序到动态 Web servlet 的通信的主要内容,如果未能解决你的问题,请参考以下文章

什么是Servlet?

java web-----servlet

Servlet & Filter

从 Android 动态功能模块将资产加载到 WebView

Servlet概念

如何从 web 应用程序实时绘制到 android 应用程序屏幕