简介:
在前些天写的项目中用到了Android与Tomcat服务器的数据交互,即“通过HttpClient的方式向服务器发送请求,服务器的Servlet接收并执行数据处理(从数据库中提取数据),最后返回给Android平台,平台解析”的过程。
配置:
服务器:Apache Tomcat v8.0
语言版本:Java 1.8.0_66
编译环境:Eclipse
Android Studio
调用jar包:httpclient-4.2.5,httpcore-4.2.4 //HttpClient父类
gson-2.2.4 //封装,解析json数据
mysql-connector-java-5.1.37-bin //用于连接Mysql数据库
服务器搭建:
Eclipse新建动态Web项目(Dynamic Web Project)并且在项目中构建简单的登陆页面,用于测试数据库连接性,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form id="from" action="Login" method="post">
<table>
<tr><td>用户名</td><td><input type="text" name="ID"></td></tr>
<tr><td>密码</td><td><input type="text" name="PW"></td></tr>
<tr><td colspan="2" align="center"><input type="submit" value="登陆"></td></tr>
</table>
</form>
</body>
</html>
前段页面构建完成,下面来搭建服务器,在Java Resources下的src文件夹中新建com.DBTool包,用作数据池来连接数据库,在包中建立DBUtil类实现功能,代码如下:
package com.DBTool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.*;
public class DBUtil {
private static String url="jdbc:mysql://localhost:3306/demodatabase";
private static String driverClass="com.mysql.jdbc.Driver";
private static String username="root";
private static String password="root";
private static Connection conn;
//装载驱动
static{
try{
Class.forName(driverClass);
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
}
//获取数据库连接
public static Connection getConnection(){
try{
conn=DriverManager.getConnection(url,username,password);
}
catch(SQLException e){
e.printStackTrace();
}
return conn;
}
//建立数据库连接
public static void main(String[] args){
Connection conn=DBUtil.getConnection();
if(conn==null){
System.out.println("数据库连接失败!");
}
}
//关闭数据库连接
public static void Clse(){
if(conn!=null){
try{
conn.close();
}
catch(SQLException e){
e.printStackTrace();
}
}
}
}
在Java Resources下的src文件夹中新建com.Servlet包,用于存放Servlet文件,也就是用来实现功能的服务器文件,在包中建立Login类,此为Servlet类。
此时在Login类中会自动生成doGet和doPost两种方法,我们对doPost方法中的代码进行删改和添加,来实现登陆功能:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String ID = request.getParameter("ID"); //用于接收前段输入的ID值,此处参数须和input控件的name值一致
String PW= request.getParameter("PW");//用于接收前段输入的PW值,此处参数须和input控件的name值一致
boolean type=false;//用于判断账号和密码是否与数据库中查询结果一致
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
try
{
Connection con=DBUtil.getConnection();
Statement stmt=con.createStatement();
String sql="select * from demodatabase.demotable where uid="+ID+" and pwd="+PW;
ResultSet rs=stmt.executeQuery(sql);
while(rs.next())
{
type=true;
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
DBUtil.Close();
out.print(type);
out.flush();
out.close();
}
}
最后,在WebContent下的WEB-INF文件夹下加入xml文件来连接servlet与jsp前端:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>com.Servlet.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
</web-app>
运行服务器,测试是否成功搭建
返回值为true,证明服务器工作流程正确,然后开始进行Android平台的作业。
Android平台登录模块:
打开Android Studio,新建空项目(Blank Activity),随便布个局,搭建登录界面:
(布局代码在Demo里)
打开MainActivity,开始编辑功能代码,在这之前需要先在lib文件夹中加入第三方jar包httpclient-4.2.5和httpcore-4.2.4,并且Add As Library。
在onCreate方法中开始加入代码:
1.获取登录按钮,加入监听事件,在监听事件中获取所输入的账号和密码,调用SendByHttpClient方法处理:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=(Button)findViewById(R.id.Login);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText uid=(EditText)findViewById(R.id.username);
EditText pwd=(EditText)findViewById(R.id.password);
String id=uid.getText().toString().trim();
String pw=pwd.getText().toString().trim();
SendByHttpClient(id,pw);
}
});
}
在onCreate方法外编写SendByHttpClient方法,其中包含id和pw两个String变量:
public void SendByHttpClient(final String id, final String pw){
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpclient=new DefaultHttpClient();
HttpPost httpPost=new HttpPost("http://192.168.191.1:8080/HttpClientDemo/Login");//服务器地址,指向Servlet
List<NameValuePair> params=new ArrayList<NameValuePair>();//将id和pw装入list
params.add(new BasicNameValuePair("ID",id));
params.add(new BasicNameValuePair("PW",pw));
final UrlEncodedFormEntity entity=new UrlEncodedFormEntity(params,"utf-8");//以UTF-8格式发送
httpPost.setEntity(entity);
HttpResponse httpResponse= httpclient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200)//在200毫秒之内接收到返回值
{
HttpEntity entity1=httpResponse.getEntity();
String response=EntityUtils.toString(entity1, "utf-8");//以UTF-8格式解析
Message message=new Message();
message.what=USER_LOGIN;
message.obj=response;
handler.sendMessage(message);使用Message传递消息给线程
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
编写线程,Message接收值,并给予显示:
public static final int SHOW_RESPONSE=1;
public Handler handler=new Handler() {
public void handleMessage(Message msg)
{
switch (msg.what){
case SHOW_RESPONSE:
String response=(String)msg.obj;
Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
最后在AndroidManifest.xml中加入 允许连接网络 的代码:
<uses-permission android:name="android.permission.INTERNET" />
结束战斗,测试结果:
注:
1.PO主采用的是真机调试,也就是服务器所在的计算机开wifi,用手机去连接,然后在http那里填写的是无线局域网适配器的ip地址即可。
查询方法:在CMD中输入ipconfig即可查看
2.完成代码后如果在Build时遇到报错问题有可能是因为多个jar包同时指向一个log文件所致,
可以在Gradele Scripts里的build.gradle(Module:app)中,找到buildTypes方法的下方添加以下代码解决:
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}