最近两个月感觉还是学了不少东西,安卓了解更加透彻,web开发也能拿的出手,php也开始上手了。总会有不想写代码的时候,这时就来总结总结学习的东西也挺好的。
现在主要存在两种网络模式,B/S和C/S。相对于B/S,C/S可能要稍微复杂一点,需要我们开发客户端。C/S可以使用tcp/ip协议和http协议进行通信。我们从简单的开始,看一下手机客户端怎么用这两种方式连接后台验证密码成功登陆。
一、使用http协议
我们需要一个web服务器,至于这个服务器怎么搭建,用servlet+jdbc还是使用hibernate,spring这些框架都是可以实现的。这里我使用的是hibernate,新建一个web工程,hibernate配置文件代码如下:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.username">XXX</property>
<property name="hibernate.connection.password">XXX</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@ip:port:dataname</property>
<property name="show_sql">true</property>
<mapping resource="com/xyj/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.xyj.hibernate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import org.hibernate.Session;
import org.junit.Test;
import com.zifeiyu.domain.Score;
import com.zifeiyu.domain.Student;
/*
* 提供数据库的查询服务,包括密码
*/
public class DBService {
public static String getPassword(String username) {
Session session = null;
try {
session = hibOracleUtils.getSession();
String hql="from User as s where s.username=?";
Query query=session.createQuery(hql);
//填充占位符
query.setString(0, username);
User user=(User) query.uniqueResult();
return user.getpassword();
}finally {
if (session != null) {
session.close();
}
}
}
}
服务器类:
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
String username= req.getParameter("username");
String password = req.getParameter("password");
System.out.println("=========username========" + username);
System.out.println("=========password========" + password);
String PASSWD;
try {
//根据用户名从数据库取出密码(数据库中存放的是md5加密后的密码,客户端传过来的也是加密后的,保证了安全性)
PASSWD = DBService.getPassword(username);
if (password.equals(PASSWD)) {
pw.print(true);
} else {
pw.print(false);
}
} catch (Exception e) {
pw.print(false);
}
}
}
这样后台服务器就搭建好了(上面仅仅贴出了重要代码),再来看看手机客户端怎么发送http请求。
package com.xyj.login;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
public class HttpClientToServer {
String urlAddress = "http://localhost:8081/AndroidServer/login.do";
public HttpClientToServer(){
}
public String doPost(String USER_XH,String password){
HttpPost httpPost = new HttpPost(urlAddress);
List params = new ArrayList();
NameValuePair pair1 = new BasicNameValuePair("username", username);
NameValuePair pair2 = new BasicNameValuePair("password", password);
params.add(pair1);
params.add(pair2);
HttpEntity he;
try {
he = new UrlEncodedFormEntity(params, "gbk");
httpPost.setEntity(he);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
HttpClient hc = new DefaultHttpClient();
try {
HttpResponse ht = hc.execute(httpPost);
if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity het = ht.getEntity();
InputStream is = het.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String response = "";
String readLine = null;
while((readLine =br.readLine()) != null){
//response = br.readLine();
response = response + readLine;
}
is.close();
br.close();
//String str = EntityUtils.toString(he);
System.out.println("========="+response);
return response;
}else{
return "error";
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "exception";
}
}
}
然后根据返回值是TRUE或者FALSE自定义提示消息就行了。
二、使用tcp/ip协议
服务器端使用jdbc连接数据库,代码如下:
package myServer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class myServerSocket {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
// 监听8888端口
try {
serverSocket = new ServerSocket(8888);
System.out.println("服务器开启");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
// 有请求接入
socket = serverSocket.accept();
//开启线程处理请求
new serverThread(socket).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package myServer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mysql.jdbc.ResultSetMetaData;
public class serverThread extends Thread {
public Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
String[] arr;
// 用于连接数据库
static String DBDrive = "com.mysql.jdbc.Driver";
static String connStr = "jdbc:mysql://localhost:3306/mydb";
// 连接对象
static Connection conn = null;
// 语句对象
PreparedStatement statement = null;
// 查询结果对象
ResultSet resultSet = null;
public serverThread(Socket socket) {
this.socket = socket;
// 连接mysql数据库
linkMySql();
}
private void linkMySql() {
// 加载数据库驱动程序
try {
Class.forName(DBDrive);
System.out.println("驱动成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connStr, "XXX", "XXX");
System.out.println("连接成功");
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
try {
dataInputStream = new DataInputStream(socket.getInputStream());
// 读取消息
String msg = dataInputStream.readUTF();
arr = msg.split(" ");
System.out.println(msg);
// 响应请求
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
try {
checkInfo();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
// 关闭相关的流
try {
if (dataInputStream != null)
dataInputStream.close();
if (dataOutputStream != null)
dataOutputStream.close();
if (socket != null)
socket.close();
if(conn!=null)
conn.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void checkInfo() throws SQLException {
String sql="select * from user where username=?";
List<Object> params=new ArrayList<Object>();
params.add(arr[0]);
//得到该用户的所有信息
Map<String, Object> map=findSimpleResult(sql,params);
//输出
System.out.println(map);
//通过键值得到密码
String psd=(String) map.get("psd");
if(psd==null){
try {
dataOutputStream.writeUTF("该用户不存在");
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
if(psd!=null&&psd.equals(arr[1]))
dataOutputStream.writeUTF("登录成功");
else
dataOutputStream.writeUTF("密码有误");
} catch (IOException e) {
e.printStackTrace();
}
}
}
//通过用户名得到该用户的所有信息
private Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException {
Map<String, Object> map=new HashMap<String,Object>();
int index=1;
statement = conn.prepareStatement(sql);
if(params!=null&&!params.isEmpty()){
for(int i=0;i<params.size();i++){
statement.setObject(index++, params.get(i));
}
}
resultSet=statement.executeQuery();
java.sql.ResultSetMetaData metaData=resultSet.getMetaData();
int col_len=metaData.getColumnCount();
while(resultSet.next()){
for(int i=0;i<col_len;i++){
String col_name=metaData.getColumnName(i+1);
Object col_value=resultSet.getObject(col_name);
if(col_value==null){
col_value="";
}
map.put(col_name, col_value);
}
}
return map;
}
}
客户端代码:
package com.xyj.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import com.xyj.help.config;
import android.os.Handler;
import android.os.Message;
public class loginclientThread extends Thread {
private String name;
private String psd;
Handler handler;
String response;
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
public loginclientThread(String name, String psd, Handler handler) {
this.name = name;
this.psd = psd;
this.handler = handler;
}
public void run() {
// 创建套接字
try {
socket = new Socket("122.207.54.5", 8888);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
// 发送请求
dataOutputStream.writeUTF(toString());
// 得到返回消息
response = dataInputStream.readUTF();
Message message = Message.obtain();
message.what = config.islogin;
message.obj = response;
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
try {
dataInputStream.close();
dataOutputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
//需要传送的参数多建议采用json传递
return name + " " + psd + " ";
}
}
以上就是这两种协议通信的主要代码。每天进步一点点,我们都可以非常棒