赞
踩
本文的知识点包括android客户端的网络编程、消息机制、IO流、多线程和java web服务器端的servlet、数据库操作、javabean技术、工具类和测试类的使用。
客户端
运行效果图
布局文件
activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout 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:orientation="vertical"
- tools:context="com.ningxiaojian.clientlogindemo.MainActivity">
-
- <EditText
- android:id="@+id/et_username"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="请输入登录账号"/>
-
- <EditText
- android:id="@+id/et_password"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:hint="请输入登录密码"/>
-
- <Button
- android:id="@+id/bt_login"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="登录"
- android:onClick="login"/>
-
- <Button
- android:id="@+id/bt_register"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="注册"
- android:onClick="register"/>
-
-
- </LinearLayout>
程序主入口
MainActivity
- package com.ningxiaojian.clientlogindemo;
-
- import android.annotation.SuppressLint;
- import android.os.Handler;
- import android.os.Message;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.EditText;
- import android.widget.Toast;
-
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.net.URLConnection;
- import java.net.URLEncoder;
-
- public class MainActivity extends AppCompatActivity {
-
- private EditText username;
- private EditText password;
- private String usernameStr;
- private String passwordStr;
- private final int LOGINSUCCESS=0;
- private final int LOGINNOTFOUND=1;
- private final int LOGINEXCEPT=2;
- private final int REGISTERSUCCESS=3;
- private final int REGISTERNOTFOUND=4;
- private final int REGISTEREXCEPT=5;
-
- @SuppressLint("HandlerLeak")
- Handler handler=new Handler(){//消息机制,用来在子线程中更新UI
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what){//具体消息,具体显示
- case LOGINSUCCESS:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- case LOGINNOTFOUND:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- case LOGINEXCEPT:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- case REGISTERSUCCESS:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- case REGISTERNOTFOUND:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- case REGISTEREXCEPT:
- Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
- break;
- }
- }
- };
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //找到我们需要的控件
- username = (EditText) findViewById(R.id.et_username);
- password = (EditText) findViewById(R.id.et_password);
-
-
- }
- //登录按钮的点击事件,也可以用set监听器的方法,不过这种方法简单
- public void login(View v){
- //获取编辑框内的内容
- usernameStr = username.getText().toString().trim();
- passwordStr = password.getText().toString().trim();
-
- //判断是否输入为空(在这里就不再进行正则表达式判断了)
- if(usernameStr.equals("") || passwordStr.equals("")){
- Toast.makeText(MainActivity.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
- }//进行登录操作(联网操作要添加权限)
- else {
- //联网操作要开子线程,在主线程不能更新UI
- new Thread(){
-
- private HttpURLConnection connection;
-
-
- @Override
- public void run() {
-
- try {
- //封装成传输数据的键值对,无论get还是post,传输中文时都要进行url编码(RULEncoder)
- // 如果是在浏览器端的话,它会自动进行帮我们转码,不用我们进行手动设置
- String data2= "username="+ URLEncoder.encode(usernameStr,"utf-8")+"&password="+ URLEncoder.encode(passwordStr,"utf-8")+"&sign="+URLEncoder.encode("1","utf-8");
- connection=HttpConnectionUtils.getConnection(data2);
- int code = connection.getResponseCode();
- if(code==200){
- InputStream inputStream = connection.getInputStream();
- String str = StreamChangeStrUtils.toChange(inputStream);//写个工具类流转换成字符串
- Message message = Message.obtain();//更新UI就要向消息机制发送消息
- message.what=LOGINSUCCESS;//用来标志是哪个消息
- message.obj=str;//消息主体
- handler.sendMessage(message);
-
- }
- else {
- Message message = Message.obtain();
- message.what=LOGINNOTFOUND;
- message.obj="注册异常...请稍后再试";
- handler.sendMessage(message);
- }
- } catch (Exception e) {//会抛出很多个异常,这里抓一个大的异常
- e.printStackTrace();
- Message message = Message.obtain();
- message.what=LOGINEXCEPT;
- message.obj="服务器异常...请稍后再试";
- handler.sendMessage(message);
- }
- }
- }.start();//不要忘记开线程
- }
- }
- //注册按钮的点击事件
- public void register(View v){
- usernameStr = username.getText().toString().trim();
- passwordStr = password.getText().toString().trim();
- if(usernameStr.equals("") || passwordStr.equals("")){
- Toast.makeText(MainActivity.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
- }
- else {
- new Thread(){
-
- HttpURLConnection connection=null;
- @Override
- public void run() {
- try {
- String data= "username="+ URLEncoder.encode(usernameStr,"utf-8")+"&password="+ URLEncoder.encode(passwordStr,"utf-8")+"&sign="+URLEncoder.encode("2","utf-8");
- connection=HttpConnectionUtils.getConnection(data);
- int code = connection.getResponseCode();
- if(code==200){
- InputStream inputStream = connection.getInputStream();
- String str = StreamChangeStrUtils.toChange(inputStream);
- Message message = Message.obtain();
- message.obj=str;
- message.what=REGISTERSUCCESS;
- handler.sendMessage(message);
- }
- else {
- Message message = Message.obtain();
- message.what=REGISTERNOTFOUND;
- message.obj="注册异常...请稍后再试";
- handler.sendMessage(message);
- }
- } catch (Exception e) {
- e.printStackTrace();
- Message message = Message.obtain();
- message.what=REGISTEREXCEPT;
- message.obj="服务器异常...请稍后再试";
- handler.sendMessage(message);
- }
-
- }
- }.start();//不要忘记开线程
-
- }
- }
- }
-
流转换成字符串的工具类
StreamChangeStrUtils
- package com.ningxiaojian.clientlogindemo;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- /**
- * 流转换成字符串的工具类
- */
-
- public class StreamChangeStrUtils {
- public static String toChange(InputStream inputStream) throws Exception {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();//数组流,在流的内部有个缓冲区,可以进行转换成字节
- //下面是属于io流的知识,在此不再赘述
- byte b[]=new byte[1024];
- int len=-1;
- while ((len=inputStream.read(b))!=-1){
- bos.write(b,0,len);
- }
- inputStream.close();//关闭流,数组流会自动关闭,关闭是否都可以
- String str = new String(bos.toByteArray());
- //服务器默认返回的是gbk,如果要在android端解决乱码,可以在此设置为gbk,一般提倡的是服务器解决
- // 让服务器给我们返回utf-8,因为在android本地默认的是utf-8
- return str;
- }
- }
联网工具类
HttpConnectionUtils
- package com.ningxiaojian.clientlogindemo;
-
- import android.os.Message;
-
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.HttpURLConnection;
- import java.net.ProtocolException;
- import java.net.URL;
- import java.net.URLEncoder;
-
- /**
- * 获取联网连接
- * Created by Justin on 2018/4/16.
- */
-
- public class HttpConnectionUtils {
- public static HttpURLConnection getConnection(String data) throws Exception {
-
- //通过URL对象获取联网对象
- URL url= new URL("http://192.168.1.104:8080/AndroidLoginDemo/LoginServlet");
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setRequestMethod("POST");//设置post请求
- connection.setReadTimeout(5000);//设置5s的响应时间
- connection.setDoOutput(true);//允许输出
- connection.setDoInput(true);//允许输入
- //设置请求头,以键值对的方式传输(以下这两点在GET请求中不用设置)
- connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded ");
- connection.setRequestProperty("Content-Length",data.length()+"");//设置请求体的长度
- OutputStream outputStream = connection.getOutputStream();
- outputStream.write(data.getBytes());//进行传输操作
- //判断服务端返回的响应码,这里是http协议的内容
- return connection;
- }
- }
联网操作一定要在
AndroidManifest.xml加上权限
<uses-permission android:name="android.permission.INTERNET"/> 服务器端(Tomcat) 首先去mysql创建一个数据库,表结构如下 因为使用到mysql,所以要把jdbc的驱动类添加到webcontent->web-inf->lib中 mysql-connector-java-5.1.45-bin.jar 在eclipse创建以下包名 com.ningxiaojian.dao:dao层接口 com.ningxiaojian.dao.impl:dao层接口的实现 com.ningxiaojian.domain:javabean对象 com.ningxiaojian.service:逻辑层的接口 com.ningxiaojian.service.impl:逻辑层的实现 com.ningxiaojian.web.control:存放servlet com.ningxiaojian.utils:存放工具类 com.ninxiaojian.test:存放测试类 创建java对象 User.java
- package com.ningxiaojian.domain;
-
- /**
- *
- *设置一个javabean对象,用来封装dao层取出的数据
- * @author Justin
- *
- */
- public class User {
- private String username;
- private String password;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
-
- }
- package com.ningxiaojian.dao;
-
- import java.util.List;
-
- import com.ningxiaojian.domain.User;
-
- public interface UserDao {
- //找到所有元素,用来验证登录信息
- public List<User> findAll();
- //插入元素,用来注册
- public void insertElement(User people);
-
- }
dao层实现类
- package com.ningxiaojian.dao.impl;
-
- 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.List;
-
- import com.ningxiaojian.dao.UserDao;
- import com.ningxiaojian.domain.User;
- import com.ningxiaojian.utils.JDBCUtils;
-
- public class UserDaoImpl implements UserDao {
-
- Connection connection=null;
- PreparedStatement ps=null;
- ResultSet rs=null;
-
- /**
- * dao层,从数据库里面取出数据
- */
- @Override
- public List<User> findAll() {
- List<User> list=null;
- try {
- //通过工具类获得连接
- connection = JDBCUtils.getConnetion();
- //通过连接对象获取操作数据库的对象
- String sql="SELECT * FROM user;";//查询sql语句
- ps=connection.prepareStatement(sql);
- //返回查询结果集
- rs=ps.executeQuery();
- //遍历rs,并封装数据
- list=new ArrayList<User>();
- while(rs.next()) {
- User user=new User();
- user.setUsername(rs.getString(2));//索引从1开始,id参数不用取
- user.setPassword(rs.getString(3));
- list.add(user);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- finally{
- JDBCUtils.close(connection, ps, rs);//关闭连接
-
- }
- return list;
- }
-
- @Override
- public void insertElement(User people) {
- try {
- connection=JDBCUtils.getConnetion();
- String sql="INSERT INTO user(username,password) VALUES(?,?);";//插入语句
- ps=connection.prepareStatement(sql);
- ps.setString(1,people.getUsername());//使用prepareStatement可以防止sql注入
- ps.setString(2,people.getPassword());
- //执行更新语句
- ps.executeUpdate();
- } catch (Exception e) {
- e.printStackTrace();
- }
- finally {
- JDBCUtils.close(connection, ps, rs);
- }
- }
-
- }
- package com.ningxiaojian.utils;
-
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
-
-
-
- /**
- * 因为要多次用到以下的步骤,所以写一个工具类来操作jdbc
- * @author Justin
- *在这里不要导错包,import com.mysql.jdbc.PreparedStatement;是错的
- */
- public class JDBCUtils {
- /**
- * 获得jdbc连接
- */
- static Connection connection=null;
- public static Connection getConnetion() throws Exception {
- //加载jdbc驱动
- Class.forName("com.mysql.jdbc.Driver");
- //创建连接数据库的路径
- String url = "jdbc:mysql://localhost/android_login?user=root&password=12345";
- //通过url获得与数据库的连接
- connection = DriverManager.getConnection(url);
- return connection;
- }
-
- public static void close(Connection connection,PreparedStatement ps,ResultSet rs) {
- //一定要确保关闭连接,以下关闭步骤是参照官方文档的,有权威性
- if(rs!=null) {
- try {
- rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if(ps!=null) {
- try {
- ps.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- if(connection!=null) {
- try {
- connection.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
- package com.ninxiaojian.test;
-
- import java.util.List;
-
- import org.junit.jupiter.api.Test;
-
- import com.ningxiaojian.dao.UserDao;
- import com.ningxiaojian.dao.impl.UserDaoImpl;
- import com.ningxiaojian.domain.User;
-
- class TestDao {
-
- /**
- * 测试类,测试dao层那两个方法是否查询和插入正确
- */
- @Test
- void testFindAll() {
- UserDao dao=new UserDaoImpl();
- List<User> list = dao.findAll();
- for(int i=0;i<list.size();i++) {//遍历list
- User user=list.get(i);
- System.out.println("username:"+user.getUsername());
- System.out.println("password:"+user.getPassword());
- }
- }
- @Test
- void testInsertElement() {
- UserDao dao=new UserDaoImpl();
- User people=new User();
- people.setUsername("hhhhh");
- people.setPassword("66666");
- dao.insertElement(people);
- }
-
- }
- package com.ningxiaojian.web.control;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import com.ningxiaojian.domain.User;
- import com.ningxiaojian.service.UserService;
- import com.ningxiaojian.service.impl.UserServiceImpl;
-
-
- @WebServlet("/LoginServlet")
- public class LoginServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
-
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- request.setCharacterEncoding("UTF-8");//解决请求乱码(post)
- response.setCharacterEncoding("UTF-8");//解决响应乱码,下面要以字符流输出(若字节流输出则要再次编码)
- String username=request.getParameter("username");
- String password=request.getParameter("password");
- String sign=request.getParameter("sign");
- PrintWriter out=response.getWriter();
- //把传来的数据封装进javabean中
- User user=new User();
- user.setUsername(username);
- user.setPassword(password);
- UserService service=new UserServiceImpl();
- if("1".equals(sign)) {//登录操作(设置了一个标记)
- String loginInfo=service.checkLogin(user);
- out.print(loginInfo);
- }
- else if("2".equals(sign)) {//注册操作
- String registerInfo=service.register(user);
- out.print(registerInfo);
- }
-
- System.out.println(username);//在控制台输出
- System.out.println(password);
- System.out.println(sign);
-
-
- }
-
-
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
-
- }
- package com.ningxiaojian.service;
-
- import com.ningxiaojian.domain.User;
-
- public interface UserService {
- //查验登录
- public String checkLogin(User user);
- //注册用户
- public String register(User user);
- }
- package com.ningxiaojian.service.impl;
-
- import java.util.List;
-
- import com.ningxiaojian.dao.UserDao;
- import com.ningxiaojian.dao.impl.UserDaoImpl;
- import com.ningxiaojian.domain.User;
- import com.ningxiaojian.service.UserService;
-
- public class UserServiceImpl implements UserService {
-
- UserDao dao=new UserDaoImpl();
-
- /*
- * 主要的逻辑实现
- */
- @Override
- public String checkLogin(User user) {
- List<User> list = dao.findAll();
- for(int i=0;i<list.size();i++) {//遍历集合
- User user2=list.get(i);
- if(user2.getUsername().equals(user.getUsername()) && user2.getPassword().equals(user.getPassword())) {
- return "登录成功";
- }
- }
- return "登录失败,密码输入错误";
- }
-
- @Override
- public String register(User user) {
- List<User> list = dao.findAll();
- for(int i=0;i<list.size();i++) {
- User user2=list.get(i);
- if(user2.getUsername().equals(user.getUsername())) {
- return "注册失败,该用户名已存在!";
- }
- }
- dao.insertElement(user);
- return "注册成功";
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。