Android登录客户端
PS:现在只实现了注册功能,但是登录功能是一个道理,看完注册应该都会。
1、首先搭建登录界面
插一句:利用inputType
属性实现EditText
输入一行回车换行。
1
| android:inputType="text"
|
代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">
<RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0.15"></RelativeLayout>
<LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0.7" android:orientation="vertical">
<com.example.activity.smartparking.CircleImageView android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" android:layout_marginTop="130dp" android:src="@drawable/swpu"/>
<LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="18sp" android:text="账号"/> <EditText android:id="@+id/account_r" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="请输入账号" android:maxLength="10" android:layout_gravity="center_vertical"/> </LinearLayout>
<LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="18sp" android:text="密码"/> <EditText android:id="@+id/password_r" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="请输入密码" android:maxLength="10" android:layout_gravity="center_vertical" android:inputType="textPassword"/> </LinearLayout>
<Button android:layout_gravity="center" android:background="@color/buttonLogin" android:id="@+id/register_r" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册"/>
</LinearLayout>
<RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="0.15"></RelativeLayout>
</LinearLayout>
|
2、信息传输
搭建好了界面之后,就需要解决数据传输的问题。我们需要将输入的账号以及密码信息传输到服务器。
不要忘了加权限!!!(用模拟器的选手本地不要用localhost,请使用10.0.0.2)
1
| <uses-permission android:name="android.permission.INTERNET" />
|
信息传输我们使用OKhttp,要使用OKhttp,我们需要导入:
1
| implementation 'com.squareup.okhttp3:okhttp:3.2.0'
|
由于OKhttp还是比较底层的,我们还是将OKhttp进行简单的封装比较好用。这里我用了一个github别人封装好的库(忘了是哪个大哥的了,忏悔一下),源码在文末。
然后我们就可以进行数据传输了,我们在Register.Activity中操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| import android.content.Intent; import android.os.Looper; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;
import com.google.gson.Gson;
import java.io.IOException; import java.util.HashMap; import java.util.Map;
import okhttp3.Call; import okhttp3.Response;
public class RegisterActivity extends AppCompatActivity implements View.OnClickListener {
private EditText account,password; private Button register; private String str1,str2; private static String url = "http://10.24.22.247:80/SmartParking/reg1"; private Map<String,String> paramsMap = null; private CallBackUtil callBackUtil = null; private String jsonstr = null;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); init(); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.register_r: str1 = account.getText().toString(); str2 = password.getText().toString(); register_f(); OkhttpUtil.okHttpPostJson(url,jsonstr,callBackUtil); } }
private void init() { account = (EditText)findViewById(R.id.account_r); password = (EditText)findViewById(R.id.password_r); register = (Button)findViewById(R.id.register_r); register.setOnClickListener(this); }
private Object register_f() { paramsMap = new HashMap<String, String>(); paramsMap.put("uname",str1); paramsMap.put("pwd",str2); Gson gson = new Gson(); jsonstr = gson.toJson(paramsMap); callBackUtil = new CallBackUtil() { @Override public Object onParseResponse(Call call, Response response) throws IOException { String resp = response.body().string(); if(resp.equals("success")){ Looper.prepare(); Toast.makeText(RegisterActivity.this, "注册成功,请登录", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(RegisterActivity.this,Login.class); startActivity(intent); Looper.loop(); return null; }else if (resp.equals("failure")){ Looper.prepare(); Toast.makeText(RegisterActivity.this, "注册失败,请重新注册", Toast.LENGTH_SHORT).show(); Looper.loop(); return null; } return null; }
@Override public void onFailure(Call call, Exception e) { Looper.prepare(); Toast.makeText(RegisterActivity.this, "注册失败", Toast.LENGTH_SHORT).show(); Looper.loop(); }
@Override public void onResponse(Object response) {
} }; return null; } }
|
3、服务器搭建
我是在本机用Tomcat服务器测试的,关于Tomcat服务器的测试,我就不在这里说了,网上教程很多。
在搭建好了Tomcat服务器之后,我们先提一个小东西,Eclipse的TCP/IP Monitor,这个东西是监听端口数据的,我们可以用它来监听Servlet的请求数据(request)和响应数据(response)。
TCP/IP Monitor打开方式:进入菜单 Window->Show View->Other,在弹出框中选择 TCP/IP Monitor 项。
空白处右键选择properties,点击 Add 添加一个新的监控。
⭐⭐设置各项属性,其中各属性含义如下:
Local monitoring port:本地的监控端口,此监控端口必须未被使用;且设置之后,客户端程序须修改为向此端口发送请求,而不是之前的服务器接收的端口;
Host name:服务器地址(这里是本机);
Port:服务器端口;
Type:HTTP/HTTPS,根据实际使用协议选择;
Timeout:monitor在尝试重连之前的等待时间。
简单来讲,假设你开始访问的地址是:http://10.24.22.247:8080/SmartParking/reg1,现在你就需要将你之前设置的端口改为上面的Local monitoring port端口,即改为http://10.24.22.247:80/SmartParking/reg1,TCP/IP Monitor会将发往端口80的数据转发给你实际用到的端口8080。
4、服务器处理请求(request)及返回(response)
写这个之前我想先说说服务起的相关知识,前文所提到的访问地址,如http://10.24.22.247:8080/SmartParking/reg1之类的信息具体指什么呢?
10.24.22.247 是你服务器的ip地址(这里提一句,如果你是在模拟器上运行的话,这里不能填localhost,需要你电脑在公网下面的私网ip(cmd输入ipconfig找到ipv4就是你的ip了,校园网的话可能一段时间会换,自己注意下)。
8080就是端口号了,我们电脑的端口很多,只要用不被占用的就行了。
SmartParking/reg1就是你的SmartParking工程下的某一个servlet,我们通过reg1将真实地址隐藏了(我这里学的不是很明白,懂得应该都能懂,没有学过servlet的建议去B站找找servlet的资源听一下,很简单的,听两节servlet基础就行了)。
反正经过上面的东东,我们就可以访问到我们自己的服务器资源了。
先把代码列出来(需要自己导入JDBK数据库操作的jar包),简单说一下:就是客户端通过OKhttp发送数据给服务器(这一步就是请求request),服务器如果成功接受了数据,就会首先分析该请求是get还是post,然后在根据他的类型执行不同的方法,get请求执行doGet方法,post请求执行doPost方法(我上传的是post请求,所以只对doPost方法进行了编写)。最后执行完相应的方法之后就会返回响应给客户端,响应数据的写入也在doGet和doPost方法中写,核心内容方法是getWriter().write()。
代码中的DBHandle是封装的连接数据库以及curd方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter;
import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
public class RegisterServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.addIntHeader("ycy", 101); System.out.println(req.getRequestURI()); BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)req.getInputStream(), "utf-8")); StringBuffer sb = new StringBuffer(""); String temp,json; while ((temp = br.readLine()) != null) { sb.append(temp); } br.close(); json = sb.toString(); Gson gson = new Gson(); User user = gson.fromJson(json, User.class); String uname = user.getUname(); String pwd = user.getPwd(); boolean u_exit = false; u_exit = exit(uname,u_exit); if(u_exit) { insert(uname, pwd); resp.getWriter().write("success"); }else { resp.getWriter().write("failure"); } }
private boolean exit(String uname,boolean b_exit) { DBHandler db_exit = new DBHandler(); String sql_select = "select *from user where username=?"; String a_exit = db_exit.query(sql_select, new String[] {uname});
if(a_exit.isEmpty()) { b_exit = true; return b_exit; }else { b_exit = false; return b_exit; } } private void insert(String uname, String pwd) { DBHandler db_insert = new DBHandler(); String sql = "insert into user(username,pwd) values (?,?)"; db_insert.insert(sql, new String[] {uname, pwd}); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData;
import javax.servlet.http.HttpServlet;
public class DBHandler { String url = "jdbc:mysql://localhost/parking"; String user="root"; String pwd="Qwert592665"; private Connection conn; private PreparedStatement ps; private ResultSet rs; public Connection getConn(){ try{ Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url, user, pwd); }catch(Exception ex){ ex.printStackTrace(); } return conn; } public String query(String sql,String[] args){ String result=""; try{ conn=getConn(); System.out.println(sql); ps=conn.prepareStatement(sql); for(int i=0;i<args.length;i++){ ps.setString(i+1, args[i]); } rs=ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int count=rsmd.getColumnCount(); System.out.println(count); while (rs.next()) { for(int i=1;i<=count;i++){ result+=rs.getString(i)+"*"; } } }catch (Exception ex) { ex.printStackTrace(); } return result; } public boolean insert(String sql,String[] args){ boolean flag=false; try{ conn=getConn(); System.out.println(sql); ps=conn.prepareStatement(sql); for(int i=0;i<args.length;i++){ ps.setString(i+1, args[i]); } int i=ps.executeUpdate(); System.out.println(i); if(i==1){ flag=true; } }catch (Exception ex) { ex.printStackTrace(); } return flag; } public boolean checkUser(String sql,String[] args){ boolean flag=false; try{ conn=getConn(); ps=conn.prepareStatement(sql); for(int i=0;i<args.length;i++){ ps.setString(i+1, args[i]); } rs=ps.executeQuery(); if(rs.next()){ flag=true; } }catch (Exception ex) { ex.printStackTrace(); } return flag; } public static void main(String[] args){ DBHandler dbh=new DBHandler(); String result=dbh.query( "select * from book where book_name like ? or book_author like ?", new String[] { "wandou", "123456" }); System.out.println(result); } }
|
5、最终调试
调试过程遇到很多问题就要自己解决了,但是首先应该明白一点就是要用TCP/IP Monitor来看自己的数据对不对。
左下角和右下角分别是你的request和response,里面有你的响应头和数据,首先分析自己发送的东西有没有问题,最后写东西。
6、源码
项目地址:https://github.com/HuaHuaHuaHe/LoginTest