基於servlet的服務端與安卓客戶端的通信(文本)

首先,先看一下服務端包的結構


首先是UserManager

package com.server.servelt;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Base64;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.server.service.UserService;
import com.sun.mail.util.BASE64DecoderStream;

public class UserManager extends HttpServlet {
	private static final String CODE="UTF-8";
	public UserManager()
	{
		super();
	}
	public void destroy()
	{
		super.destroy();
	}
	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException 
	{
		doPost(request, response);
	}
	public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException
	{
		//設置編碼
		response.setContentType("text/html");
		response.setCharacterEncoding(CODE);
		request.setCharacterEncoding(CODE);
		
		//獲取請求方法名,其中request_flag是我們安卓客戶端請求的參數,詳細介紹請參照servlet有關書籍
		String flag=request.getParameter("request_flag");
		System.out.println("flag="+flag);
		
		//預定義一個字符串,用來接收json
		String json="";
		if("login".equals(flag))
		{
			//此處的username和password也是安卓客戶端訪問網址的參數
			String username=request.getParameter("username");
			String password=request.getParameter("password");
			//調用UserService的login方法實現登錄
			json=UserService.login(username, password);
		}
		//控制檯輸出,方便檢驗,無特殊含義
		System.out.println("json="+json);
		//利用輸出流將登錄信息(此處爲success或是fail)反饋給客戶端
		PrintWriter out=response.getWriter();
		out.write(json);
		out.flush();
		out.close();
	
	}
}

接着是上面調用到的UserService
package com.server.service;

import com.server.dao.UserDao;
import com.server.util.JSONUtil;

public class UserService {
	public static String login(String username,String password)
	{
		//調用UserDao的login方法,該方法會查詢數據庫並對結果進行檢測,若存在該用戶,返回該用戶在數據庫中的位置,否則,返回0(位置從一開始)
		int r=UserDao.login(username,password);
		//將結果一JSONObject的形式記錄下來並返回讓輸出流反饋給客戶端
		String result=JSONUtil.createJSONString("result",r);
		return result;
	}
}

再接着是上面調用到的UserDao
package com.server.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.server.util.DBUtil;

public class UserDao {
	private static Connection conn=null;
	private static Statement sta=null;
	private static ResultSet res=null;
	
	public UserDao()
	{
		
	}
	public static int login(String username,String password)
	{
		try{
			conn=DBUtil.getConnection();
			sta=conn.createStatement();
			//注意下面的sql語句,值前後要加上單引號,同時不準存在中文字符
			String sql="select COUNT(*) from userlist where username='"+username+"' and +password='"+password+"'";
			res=sta.executeQuery(sql);
			int result=0;
			if(res!=null)
			{
				//不斷查詢,若存在,返回用戶在數據庫中的位置,否則返回0,下面的1代表數據庫的第一列,此列爲自增序號列
				while(res.next())
					result=res.getInt(1);
			}
			return result;
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return 0;
	}
}


然後是倆個工具類
package com.server.util;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DBUtil {
    //默認接口是3306,除非你做了修改哈
	private static final String URL="jdbc:mysql://localhost:3306/data";
	//下面是你的用戶名,默認爲root
	private static final String USERNAME="root";
	//在密碼出填入你的密碼
	private static final String PASSWORD="密碼";
	
	static{
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	public static Connection getConnection()
	{
		try {
			return DriverManager.getConnection(URL,USERNAME,PASSWORD);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return null;
	}
	
	public void closeDB(Connection conn,Statement statement,ResultSet res)
	{
		try{
			if(res!=null)
			{
				res.close();
			}
			if(statement!=null)
			{
				statement.close();
			}
			if(conn!=null)
			{
				conn.close();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

package com.server.util;

import net.sf.json.JSONObject;

public class JSONUtil {
	public static String createJSONString(String key ,Object value)
	{
		JSONObject jsonObject=new JSONObject();
		jsonObject.put(key, value);
		return jsonObject.toString();
	}
}

另外,在WebRoot的相關路徑(詳細路徑參考圖片)需添加以下包


其中的rt.jar位於你安裝的jdk路徑(我的是E:\Java目標文件夾\liblib下面

其他包請自行百度


另外,web.xml的配置如下(eclipse)中的開發似乎不需要配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
This is the description of my J2EE componentThis is the display name of my J2EE componentUserManagercom.server.servelt.UserManagerUserManager/servlet/UserManagerindex.jsp

至此,服務端搭建完成,爲了測試你的服務端,你可以啓動服務端後在瀏覽器中輸入以下地址:

http://localhost:8080/AndroidWebService/servlet/UserManager?request_flag=login&username=admin&password=123(用於上面的配置中有了<url-pattern>/servlet/UserManager</url-pattern>這一句,所以這裏的地址就有了servlet,所以,如果你改動了配置,這裏的地址也要做相應修改)


結果如下:


接下來是安卓客戶端:

首先是MainActivity

package com.example.servertestandroid;

import java.io.IOException;

import com.example.util.HttpUtil;
import com.example.util.JSONUtil;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
	//安卓客戶端是以網址的方式訪問服務器,此處的ip地址即爲本機地址
	//這裏的路徑其實 就是我們上面的網址,只不過在安卓中不支持localhost,所以必須寫成實質性的地址
	//另外,電腦應該鏈接網線,而手機使用電腦開啓的WiFi,倆者都用WiFi似乎不行
	public static final String REQUEST_URL = "http://ip:8080/AndroidWebService/servlet/UserManager?";

	private String username="";
	private String userpwd="";
	
	private EditText editTextUsername,editTextUserpwd;
	private Button buttonLogin;

	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		//初始化控件
		initViews();
	}
	
	private void initViews() {
		// TODO Auto-generated method stub
		editTextUsername=(EditText) findViewById(R.id.id_username);
		editTextUserpwd=(EditText) findViewById(R.id.id_userpwd);
		//此處我直接將倆個輸入框中文字設置成相應的用戶名和密碼,懶得碼字了
		editTextUsername.setText("admin");
		editTextUserpwd.setText("123");
		buttonLogin=(Button) findViewById(R.id.id_login);
		buttonLogin.setOnClickListener(clickListener);
	}
	private OnClickListener clickListener=new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			String username=editTextUsername.getText().toString();
			String password=editTextUserpwd.getText().toString();
			//設置參數
			final String params="request_flag=login&username="+username+"&password="+password;
			//開啓線程,避免影響界面與用戶的交互
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					//通過開啓httpConnection來達到訪問網址的目的,此處的result即爲服務端出發送的json
					String result = HttpUtil.sendGet(REQUEST_URL, params);
					//將上述json進行解析,得到結果(序號)
					int res=JSONUtil.getResult("result", result);
					
					if(res==1)
					{
						//線程中不能進行與界面交互,所以我們開啓一個handler來處理
						handler.sendEmptyMessage(1);
						
					}
					
				}
				//注意此處還有 一個start()
			}).start();
			
		}
	};
	Handler handler=new Handler()
	{
		
		public void handleMessage(Message message)
		{
		
			Toast.makeText(getApplicationContext(), "success",Toast.LENGTH_SHORT).show();
		}
	};
}

其次是倆個工具類

package com.example.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class HttpUtil {
	public HttpUtil()
	{
		
	}
	public static String sendGet(String request_url,String params) 
	{
		try {
			URL url = new URL(request_url+params);
		
			HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();
			httpURLConnection.setConnectTimeout(3000);
			
			httpURLConnection.setRequestMethod("GET");
			//據我的理解,應該是設置該鏈接是用來接收數據的,因爲還有一個方法是setDoIOutput
			httpURLConnection.setDoInput(true);
			//200代表HTTP_OK,可以通過鼠標移至給方法上後右鍵或是按下F3查看聲明
			if(httpURLConnection.getResponseCode()==200)
			{
				return InputStream2String(httpURLConnection.getInputStream());
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return "";
	}
	private static String InputStream2String(InputStream inputStream) throws IOException {
		// TODO Auto-generated method stub
		ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
		int len=0;
		byte[] b=new byte[1024];
		//將服務端發過來的數據讀取到b中
		while((len=inputStream.read(b))!=-1)
		{
			byteArrayOutputStream.write(b, 0, len);
		}
		return new String(byteArrayOutputStream.toByteArray());
	}
}
package com.example.util;

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



public class JSONUtil {
	/**
	 * 解析Json數據
	 * @param key
	 * @param json
	 * @return
	 */
	public static int getResult(String key,String json){
		
		try {
			JSONObject jsonObject=new JSONObject(json);
			int result=jsonObject.getInt(key);
			return result;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return -1;
	}
}

此處省略佈局文件


效果圖如下:


另外,只支持傳送文本信息,至於圖片和文件有待進一步研究

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章