基于servlet的服务端与安卓客户端的通信(文本)

本文介绍了如何使用servlet实现服务端与安卓客户端的文本通信。通过展示服务端的UserManager类和web.xml配置,以及安卓客户端的MainActivity和相关工具类,详细阐述了通信过程。在服务端,可以通过特定URL进行测试;在安卓端,实现了登录请求的发送与接收响应。

首先,先看一下服务端包的结构


首先是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



  
    This is the description of my J2EE component
    This is the display name of my J2EE component
    UserManager
    com.server.servelt.UserManager
  

  
    UserManager
    /servlet/UserManager
  
  
    index.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;
	}
}

此处省略布局文件


效果图如下:


另外,只支持传送文本信息,至于图片和文件有待进一步研究

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值