之前已经写了怎么搭建eclipse加tomcat整合成服务器环境,如果有人不知道怎么配置,可以看我的那篇博客。
现在环境搭配好的情况下,在eclipse里新建一个Web工程,在src包下新建一个servlet。
@WebServlet("/UserServlet")
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//============add
List<String> mList=new ArrayList<>();
private StringBuffer UIDS;
public UserServlet() {
super();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在服务器端解决中文乱码问题
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
if(request.getParameter("userName")==null || request.getParameter("passWord")==null){
return;
}
String userName="",passWord="";
// //根据请求类型解决中文乱码问题
if(request.getMethod().equalsIgnoreCase("GET")) {
userName = new String(request.getParameter("userName").getBytes("iso-8859-1"),"utf-8");
passWord = new String(request.getParameter("passWord").getBytes("iso-8859-1"),"utf-8");
}else{
userName = new String(request.getParameter("userName").getBytes());
passWord = new String(request.getParameter("passWord").getBytes());
}
System.out.println("账号:"+userName);
System.out.println("密码:"+passWord);
//连接数据库,使用局部变量防止并发问题
selectUser(userName,passWord,response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
private void selectUser(String userName,final String passWord,HttpServletResponse response) {
List<Person> persons=new ArrayList<>();
JDBCUtil j=new JDBCUtil();
String sql="select * from user where account = '"+userName+"' and password = '"+passWord+"'";
//新建一个json数据返回客户端
String jsonString="";
try {
ResultSet rs=j.query(sql);
if(rs.next()){
System.out.println("id"+"\t"+"账号"+"\t"+"密码"+"\t"+"摄像机名称"+"\t"+"UID"+"\t"+"用户名"+"\t"+"用户密码"+"\t");
rs.previous();
}
while(rs.next()){
int id=rs.getInt(1);
String n=rs.getString(2);
String s=rs.getString(3);
String cname=rs.getString(4);
String UID=rs.getString(5);
String name=rs.getString(6);
String cpassword=rs.getString(7);
System.out.println(id+"\t"+n+"\t"+s+"\t"+cname+"\t"+UID+"\t"+name+"\t"+cpassword+"\t");
Person person=new Person(id,n,s,cname,UID,name,cpassword);
persons.add(person);
}
//判断查询结果
if(persons.size()>0){
jsonString = JsonTools.createJsonString("strings",DataUtil.getPersons(persons));
response.getWriter().print(jsonString);
persons.clear();
}else{
response.getOutputStream().print("fail");
}
} catch (Exception e) {
// TODO: handle exception
}finally {
j.close();
}
}
}
在servlet里用到了一个实体类Person.
public class Person {
int id;
String account;
String password;
String name;
String uid;
String cname;
String cpassword;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(int id, String account, String password, String name, String uid, String cname, String cpassword) {
super();
this.id = id;
this.account = account;
this.password = password;
this.name = name;
this.uid = uid;
this.cname = cname;
this.cpassword = cpassword;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCpassword() {
return cpassword;
}
public void setCpassword(String cpassword) {
this.cpassword = cpassword;
}
// String id;
// String account;
// String password;
// String name;
// String uid;
// String cname;
// String cpassword;
@Override
public String toString() {
return "Person [id=" + id + ", account=" + account + ", password=" + password
+ ", name=" + name + ", uid=" + uid +", cname=" + cname +", cpassword=" + cpassword +"]";
}
}
然后根据接收的用户名和密码查找数据库,所有首先必须安装MySQL数据库,在网上下载MySQL数据库,具体安装可以参考http://www.jb51.net/article/23876.htm,安装完成后,最后下载一个视图工具管理Mysql,我用的是Navicat for MySQL,网上可以下载并且破解。然后新建user表,字段和Person实体类对应。随便写入一些数据。
由于连接数据库需要用的JDBC架包,所以去网上下载Mysql数据库的JDBC架包,在工程下新建lib目录,把架包拷入lib目录,让后邮寄点击架包,build path->add buildpath,把架包加入工程。这样还不够,web项目必须把架包拷入Tomcat的lib目录下,否则会报找不到架包的错误。
在src包下还有一个JDBC类,封装了数据库的操作:
public class JDBCUtil {
private static String Driver="com.mysql.jdbc.Driver";
private String url="jdbc:mysql://localhost:3306/aa?characterEncoding=utf-8";
private String user="root";
private String pwd="123456";
private Connection conn=null;
private PreparedStatement ps=null;
//1,加载驱动(一次加载)
static{
try {
Class.forName(Driver);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//2,建立连接
public void getConn(){
try {
conn=DriverManager.getConnection(url,user,pwd);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//3,创建sql对象,执行sql语句,处理结果集(增,删,改)
public int update(String sql,Object obj[]){
getConn();
int k=0;
try {
ps=conn.prepareStatement(sql);
if(obj!=null){
for(int i=0;i<obj.length;i++){
ps.setObject((i+1), (String)obj[i]);
}
}
k=ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
close();
return k;
}
//4,查询
public ResultSet query(String sql){
getConn();
ResultSet rs=null;
try {
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rs;
}
//5,释放资源
public void close(){
try {
if(ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
至此服务器的代码编写基本完成,然后编写客户端的代码。
在android端新建一个类JsonTools,负责解析服务器传回的json数据。
public static List<Person> getPersons(String key, String jsonString) { List<Person> list = new ArrayList<Person>(); JSONObject jsonObject; try { jsonObject = new JSONObject(jsonString); JSONArray Persons = jsonObject.getJSONArray(key); for (int i = 0; i < Persons.length(); i++) { Person person = new Person(); JSONObject jsonObject2 = Persons.getJSONObject(i); person.setId(jsonObject2.getInt("id")); person.setAccount(jsonObject2.getString("account")); person.setPassword(jsonObject2.getString("password")); person.setName(jsonObject2.getString("name")); person.setUid(jsonObject2.getString("uid")); person.setCname(jsonObject2.getString("cname")); person.setCpassword(jsonObject2.getString("cpassword")); list.add(person); } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; }
然后新建一个类UserService,负责发送POST请求和接收服务器返回的数据。
/** * DOPost请求 */ private static String sendPOSTRequest(String path, Map<String, String> params,String encode) throws MalformedURLException, IOException { byte[] data = getRequestData(params, encode).toString().getBytes();//获得请求体 //此处不能把path变成StringBuilder,否则会崩溃 HttpURLConnection conn=(HttpURLConnection)new URL(path).openConnection(); conn.setConnectTimeout(5000); //================= conn.setDoInput(true); //打开输入流,以便从服务器获取数据 conn.setDoOutput(true); //打开输出流,以便向服务器提交数据 conn.setRequestMethod("POST"); //设置以Post方式提交数据 conn.setUseCaches(false); // conn.setRequestProperty(); //设置请求体的类型是文本类型 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //设置请求体的长度 conn.setRequestProperty("Content-Length", String.valueOf(data.length)); OutputStream outputStream = conn.getOutputStream(); outputStream.write(data); if(conn.getResponseCode()==200) { InputStreamReader in=new InputStreamReader(conn.getInputStream()); BufferedReader bufferedReader=new BufferedReader(in); String result=""; String readLine=null; while ((readLine=bufferedReader.readLine())!=null){ result +=readLine; } in.close(); return result; } conn.disconnect(); return null; } public static String checkPost(String name, String pass) { String path="http://192.168.1.190:8080/MyWeb/UserServlet"; //将用户名和密码放入HashMap中 Map<String,String> params=new HashMap<String,String>(); params.put("userName", name); params.put("passWord", pass); try { return sendPOSTRequest(path,params,"UTF-8"); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /* * Function : 封装请求体信息 * Param : params请求体内容,encode编码格式 */ public static StringBuffer getRequestData(Map<String, String> params, String encode) { StringBuffer stringBuffer = new StringBuffer(); //存储封装好的请求体信息 try { for(Map.Entry<String, String> entry : params.entrySet()) { stringBuffer.append(entry.getKey()) .append("=") .append(URLEncoder.encode(entry.getValue(), encode)) .append("&"); } stringBuffer.deleteCharAt(stringBuffer.length() - 1); //删除最后的一个"&" } catch (Exception e) { e.printStackTrace(); } return stringBuffer; }
这其中checkPost是用来接收界面传递的用户名密码,然后封装成Map,然后调用sendPOSTRequest()发送post请求,并且返回服务器传来的json数据。getRequestData()用来把Map参数封装成Post请求的请求体。
然后就可以编写主界面的activity。
public class LoginActivity extends Activity { private EditText userName; private EditText passWord; //=============== private String result=null; private TextView mTextView; private List<Person> mPersons =new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); userName=(EditText)this.findViewById(R.id.userName); passWord=(EditText)this.findViewById(R.id.password); mTextView= (TextView) findViewById(R.id.tv_info); findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { login(); } }); findViewById(R.id.btn_connectPost).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { loginPost(); } }); } private void clearEditTexts() { // userName.setText(""); // passWord.setText(""); result=null; } /** * 用户登录的方法 */ public void login() { //取得用户输入的账号和密码 final String name=userName.getText().toString(); final String pass=passWord.getText().toString(); new Thread(new Runnable() { @Override public void run() { result=UserService.check(name,pass); runOnUiThread(new Runnable() { @Override public void run() { if (result!=null){ if (result.equals("fail")){ Toast.makeText(LoginActivity.this,"fail",Toast.LENGTH_LONG).show(); clearEditTexts(); }else { mTextView.setText(result); } }else { Toast.makeText(LoginActivity.this,"null",Toast.LENGTH_LONG).show(); } } }); } }).start(); } /** * 采用post请求 */ public void loginPost() { //取得用户输入的账号和密码 final String name=userName.getText().toString(); final String pass=passWord.getText().toString(); new Thread(new Runnable() { @Override public void run() { result=UserService.checkPost(name,pass); runOnUiThread(new Runnable() { @Override public void run() { if (result!=null){ if (result.equals("fail")||result.equals("")){ Toast.makeText(LoginActivity.this,"用户名或密码错误",Toast.LENGTH_LONG).show(); clearEditTexts(); }else { mPersons= JsonTools.getPersons("strings",result); StringBuffer buffer=new StringBuffer(); for (int i=0;i<mPersons.size();i++){ Person Person=mPersons.get(i); buffer.append(Person.getId()+"\t"+Person.getAccount()+"\t"+Person.getPassword()+"\t"+Person.getName()+"\t"+Person.getUid()+"\t"+Person.getCname()+"\t"+Person.getCpassword()+"\t"); buffer.append("\r\n"); } mTextView.setText(buffer.toString()); clearEditTexts(); } }else { Toast.makeText(LoginActivity.this,"访问服务器失败",Toast.LENGTH_LONG).show(); } } }); } }).start(); } }
界面的布局很简单
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/tv_info" android:text="hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_below="@+id/tv_info" android:id="@+id/mLiner"> <Button android:text="ConnectGet" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/btn_connect"/> <Button android:text="ConnectPost" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:id="@+id/btn_connectPost"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="48dp" android:layout_below="@+id/liner" android:orientation="horizontal" android:gravity="center_vertical"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="密码:" android:gravity="center|left" android:textSize="15sp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:id="@+id/password" android:password="true" android:textSize="15sp" android:background="@drawable/bg_edittext" android:padding="5dp" android:textCursorDrawable="@null" /> </LinearLayout> <LinearLayout android:id="@+id/liner" android:layout_width="match_parent" android:layout_height="48dp" android:orientation="horizontal" android:gravity="center_vertical" android:layout_below="@+id/mLiner" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="用户名:" android:gravity="center|left" android:textSize="15sp" /> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:id="@+id/userName" android:textSize="15sp" android:padding="5dp" android:background="@drawable/bg_edittext" android:textCursorDrawable="@null"/> </LinearLayout> </RelativeLayout>
其中editText是自定义的样式,如果报错可以把样式删除,或者参考我的另一篇博客EditText的设置边框样式。
由于访问网络,所有manifest文件记得加入网络权限
<uses-permission android:name="android.permission.INTERNET"/>
这样,一个android客户端就完成了。
由于此次博客的内容量太大,我感觉很难讲明白,不过效果完全可以做出来。做android开发的可以看看,我觉得会些服务器的知识才能更好的做android开发。如果大家有什么问题,欢迎给我留言,我看到后会回复。