之前已经写了怎么搭建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开发。如果大家有什么问题,欢迎给我留言,我看到后会回复。