当前位置:   article > 正文

android与java web交互完成简单的登录和注册_android 调用java 做的webservice登录功能

android 调用java 做的webservice登录功能

   本文的知识点包括android客户端的网络编程、消息机制、IO流、多线程和java web服务器端的servlet、数据库操作、javabean技术、工具类和测试类的使用。

客户端

运行效果图


布局文件

activity_main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context="com.ningxiaojian.clientlogindemo.MainActivity">
  8. <EditText
  9. android:id="@+id/et_username"
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:hint="请输入登录账号"/>
  13. <EditText
  14. android:id="@+id/et_password"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:hint="请输入登录密码"/>
  18. <Button
  19. android:id="@+id/bt_login"
  20. android:layout_width="wrap_content"
  21. android:layout_height="wrap_content"
  22. android:text="登录"
  23. android:onClick="login"/>
  24. <Button
  25. android:id="@+id/bt_register"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:text="注册"
  29. android:onClick="register"/>
  30. </LinearLayout>
程序主入口
MainActivity

  1. package com.ningxiaojian.clientlogindemo;
  2. import android.annotation.SuppressLint;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.os.Bundle;
  7. import android.view.View;
  8. import android.widget.EditText;
  9. import android.widget.Toast;
  10. import java.io.InputStream;
  11. import java.io.OutputStream;
  12. import java.io.UnsupportedEncodingException;
  13. import java.net.HttpURLConnection;
  14. import java.net.MalformedURLException;
  15. import java.net.URL;
  16. import java.net.URLConnection;
  17. import java.net.URLEncoder;
  18. public class MainActivity extends AppCompatActivity {
  19. private EditText username;
  20. private EditText password;
  21. private String usernameStr;
  22. private String passwordStr;
  23. private final int LOGINSUCCESS=0;
  24. private final int LOGINNOTFOUND=1;
  25. private final int LOGINEXCEPT=2;
  26. private final int REGISTERSUCCESS=3;
  27. private final int REGISTERNOTFOUND=4;
  28. private final int REGISTEREXCEPT=5;
  29. @SuppressLint("HandlerLeak")
  30. Handler handler=new Handler(){//消息机制,用来在子线程中更新UI
  31. @Override
  32. public void handleMessage(Message msg) {
  33. switch (msg.what){//具体消息,具体显示
  34. case LOGINSUCCESS:
  35. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  36. break;
  37. case LOGINNOTFOUND:
  38. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  39. break;
  40. case LOGINEXCEPT:
  41. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  42. break;
  43. case REGISTERSUCCESS:
  44. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  45. break;
  46. case REGISTERNOTFOUND:
  47. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  48. break;
  49. case REGISTEREXCEPT:
  50. Toast.makeText(getApplicationContext(),(String)msg.obj,Toast.LENGTH_LONG).show();
  51. break;
  52. }
  53. }
  54. };
  55. @Override
  56. protected void onCreate(Bundle savedInstanceState) {
  57. super.onCreate(savedInstanceState);
  58. setContentView(R.layout.activity_main);
  59. //找到我们需要的控件
  60. username = (EditText) findViewById(R.id.et_username);
  61. password = (EditText) findViewById(R.id.et_password);
  62. }
  63. //登录按钮的点击事件,也可以用set监听器的方法,不过这种方法简单
  64. public void login(View v){
  65. //获取编辑框内的内容
  66. usernameStr = username.getText().toString().trim();
  67. passwordStr = password.getText().toString().trim();
  68. //判断是否输入为空(在这里就不再进行正则表达式判断了)
  69. if(usernameStr.equals("") || passwordStr.equals("")){
  70. Toast.makeText(MainActivity.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
  71. }//进行登录操作(联网操作要添加权限)
  72. else {
  73. //联网操作要开子线程,在主线程不能更新UI
  74. new Thread(){
  75. private HttpURLConnection connection;
  76. @Override
  77. public void run() {
  78. try {
  79. //封装成传输数据的键值对,无论get还是post,传输中文时都要进行url编码(RULEncoder)
  80. // 如果是在浏览器端的话,它会自动进行帮我们转码,不用我们进行手动设置
  81. String data2= "username="+ URLEncoder.encode(usernameStr,"utf-8")+"&password="+ URLEncoder.encode(passwordStr,"utf-8")+"&sign="+URLEncoder.encode("1","utf-8");
  82. connection=HttpConnectionUtils.getConnection(data2);
  83. int code = connection.getResponseCode();
  84. if(code==200){
  85. InputStream inputStream = connection.getInputStream();
  86. String str = StreamChangeStrUtils.toChange(inputStream);//写个工具类流转换成字符串
  87. Message message = Message.obtain();//更新UI就要向消息机制发送消息
  88. message.what=LOGINSUCCESS;//用来标志是哪个消息
  89. message.obj=str;//消息主体
  90. handler.sendMessage(message);
  91. }
  92. else {
  93. Message message = Message.obtain();
  94. message.what=LOGINNOTFOUND;
  95. message.obj="注册异常...请稍后再试";
  96. handler.sendMessage(message);
  97. }
  98. } catch (Exception e) {//会抛出很多个异常,这里抓一个大的异常
  99. e.printStackTrace();
  100. Message message = Message.obtain();
  101. message.what=LOGINEXCEPT;
  102. message.obj="服务器异常...请稍后再试";
  103. handler.sendMessage(message);
  104. }
  105. }
  106. }.start();//不要忘记开线程
  107. }
  108. }
  109. //注册按钮的点击事件
  110. public void register(View v){
  111. usernameStr = username.getText().toString().trim();
  112. passwordStr = password.getText().toString().trim();
  113. if(usernameStr.equals("") || passwordStr.equals("")){
  114. Toast.makeText(MainActivity.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
  115. }
  116. else {
  117. new Thread(){
  118. HttpURLConnection connection=null;
  119. @Override
  120. public void run() {
  121. try {
  122. String data= "username="+ URLEncoder.encode(usernameStr,"utf-8")+"&password="+ URLEncoder.encode(passwordStr,"utf-8")+"&sign="+URLEncoder.encode("2","utf-8");
  123. connection=HttpConnectionUtils.getConnection(data);
  124. int code = connection.getResponseCode();
  125. if(code==200){
  126. InputStream inputStream = connection.getInputStream();
  127. String str = StreamChangeStrUtils.toChange(inputStream);
  128. Message message = Message.obtain();
  129. message.obj=str;
  130. message.what=REGISTERSUCCESS;
  131. handler.sendMessage(message);
  132. }
  133. else {
  134. Message message = Message.obtain();
  135. message.what=REGISTERNOTFOUND;
  136. message.obj="注册异常...请稍后再试";
  137. handler.sendMessage(message);
  138. }
  139. } catch (Exception e) {
  140. e.printStackTrace();
  141. Message message = Message.obtain();
  142. message.what=REGISTEREXCEPT;
  143. message.obj="服务器异常...请稍后再试";
  144. handler.sendMessage(message);
  145. }
  146. }
  147. }.start();//不要忘记开线程
  148. }
  149. }
  150. }
流转换成字符串的工具类
StreamChangeStrUtils
  1. package com.ningxiaojian.clientlogindemo;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. /**
  6. * 流转换成字符串的工具类
  7. */
  8. public class StreamChangeStrUtils {
  9. public static String toChange(InputStream inputStream) throws Exception {
  10. ByteArrayOutputStream bos = new ByteArrayOutputStream();//数组流,在流的内部有个缓冲区,可以进行转换成字节
  11. //下面是属于io流的知识,在此不再赘述
  12. byte b[]=new byte[1024];
  13. int len=-1;
  14. while ((len=inputStream.read(b))!=-1){
  15. bos.write(b,0,len);
  16. }
  17. inputStream.close();//关闭流,数组流会自动关闭,关闭是否都可以
  18. String str = new String(bos.toByteArray());
  19. //服务器默认返回的是gbk,如果要在android端解决乱码,可以在此设置为gbk,一般提倡的是服务器解决
  20. // 让服务器给我们返回utf-8,因为在android本地默认的是utf-8
  21. return str;
  22. }
  23. }

   联网工具类

HttpConnectionUtils

  1. package com.ningxiaojian.clientlogindemo;
  2. import android.os.Message;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.HttpURLConnection;
  6. import java.net.ProtocolException;
  7. import java.net.URL;
  8. import java.net.URLEncoder;
  9. /**
  10. * 获取联网连接
  11. * Created by Justin on 2018/4/16.
  12. */
  13. public class HttpConnectionUtils {
  14. public static HttpURLConnection getConnection(String data) throws Exception {
  15. //通过URL对象获取联网对象
  16. URL url= new URL("http://192.168.1.104:8080/AndroidLoginDemo/LoginServlet");
  17. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  18. connection.setRequestMethod("POST");//设置post请求
  19. connection.setReadTimeout(5000);//设置5s的响应时间
  20. connection.setDoOutput(true);//允许输出
  21. connection.setDoInput(true);//允许输入
  22. //设置请求头,以键值对的方式传输(以下这两点在GET请求中不用设置)
  23. connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded ");
  24. connection.setRequestProperty("Content-Length",data.length()+"");//设置请求体的长度
  25. OutputStream outputStream = connection.getOutputStream();
  26. outputStream.write(data.getBytes());//进行传输操作
  27. //判断服务端返回的响应码,这里是http协议的内容
  28. return connection;
  29. }
  30. }
   联网操作一定要在
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
  1. package com.ningxiaojian.domain;
  2. /**
  3. *
  4. *设置一个javabean对象,用来封装dao层取出的数据
  5. * @author Justin
  6. *
  7. */
  8. public class User {
  9. private String username;
  10. private String password;
  11. public String getUsername() {
  12. return username;
  13. }
  14. public void setUsername(String username) {
  15. this.username = username;
  16. }
  17. public String getPassword() {
  18. return password;
  19. }
  20. public void setPassword(String password) {
  21. this.password = password;
  22. }
  23. }

dao层接口
UserDao.java
  1. package com.ningxiaojian.dao;
  2. import java.util.List;
  3. import com.ningxiaojian.domain.User;
  4. public interface UserDao {
  5. //找到所有元素,用来验证登录信息
  6. public List<User> findAll();
  7. //插入元素,用来注册
  8. public void insertElement(User people);
  9. }
dao层实现类
UserDaoImpl.java
  1. package com.ningxiaojian.dao.impl;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import com.ningxiaojian.dao.UserDao;
  10. import com.ningxiaojian.domain.User;
  11. import com.ningxiaojian.utils.JDBCUtils;
  12. public class UserDaoImpl implements UserDao {
  13. Connection connection=null;
  14. PreparedStatement ps=null;
  15. ResultSet rs=null;
  16. /**
  17. * dao层,从数据库里面取出数据
  18. */
  19. @Override
  20. public List<User> findAll() {
  21. List<User> list=null;
  22. try {
  23. //通过工具类获得连接
  24. connection = JDBCUtils.getConnetion();
  25. //通过连接对象获取操作数据库的对象
  26. String sql="SELECT * FROM user;";//查询sql语句
  27. ps=connection.prepareStatement(sql);
  28. //返回查询结果集
  29. rs=ps.executeQuery();
  30. //遍历rs,并封装数据
  31. list=new ArrayList<User>();
  32. while(rs.next()) {
  33. User user=new User();
  34. user.setUsername(rs.getString(2));//索引从1开始,id参数不用取
  35. user.setPassword(rs.getString(3));
  36. list.add(user);
  37. }
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. finally{
  42. JDBCUtils.close(connection, ps, rs);//关闭连接
  43. }
  44. return list;
  45. }
  46. @Override
  47. public void insertElement(User people) {
  48. try {
  49. connection=JDBCUtils.getConnetion();
  50. String sql="INSERT INTO user(username,password) VALUES(?,?);";//插入语句
  51. ps=connection.prepareStatement(sql);
  52. ps.setString(1,people.getUsername());//使用prepareStatement可以防止sql注入
  53. ps.setString(2,people.getPassword());
  54. //执行更新语句
  55. ps.executeUpdate();
  56. } catch (Exception e) {
  57. e.printStackTrace();
  58. }
  59. finally {
  60. JDBCUtils.close(connection, ps, rs);
  61. }
  62. }
  63. }

jdbc工具类
JDBCUtils.java

  1. package com.ningxiaojian.utils;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. /**
  8. * 因为要多次用到以下的步骤,所以写一个工具类来操作jdbc
  9. * @author Justin
  10. *在这里不要导错包,import com.mysql.jdbc.PreparedStatement;是错的
  11. */
  12. public class JDBCUtils {
  13. /**
  14. * 获得jdbc连接
  15. */
  16. static Connection connection=null;
  17. public static Connection getConnetion() throws Exception {
  18. //加载jdbc驱动
  19. Class.forName("com.mysql.jdbc.Driver");
  20. //创建连接数据库的路径
  21. String url = "jdbc:mysql://localhost/android_login?user=root&password=12345";
  22. //通过url获得与数据库的连接
  23. connection = DriverManager.getConnection(url);
  24. return connection;
  25. }
  26. public static void close(Connection connection,PreparedStatement ps,ResultSet rs) {
  27. //一定要确保关闭连接,以下关闭步骤是参照官方文档的,有权威性
  28. if(rs!=null) {
  29. try {
  30. rs.close();
  31. } catch (SQLException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. if(ps!=null) {
  36. try {
  37. ps.close();
  38. } catch (SQLException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. if(connection!=null) {
  43. try {
  44. connection.close();
  45. } catch (SQLException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. }
  50. }

测试dao层方法的test类(仅作测试作用)
TestDao.java
  1. package com.ninxiaojian.test;
  2. import java.util.List;
  3. import org.junit.jupiter.api.Test;
  4. import com.ningxiaojian.dao.UserDao;
  5. import com.ningxiaojian.dao.impl.UserDaoImpl;
  6. import com.ningxiaojian.domain.User;
  7. class TestDao {
  8. /**
  9. * 测试类,测试dao层那两个方法是否查询和插入正确
  10. */
  11. @Test
  12. void testFindAll() {
  13. UserDao dao=new UserDaoImpl();
  14. List<User> list = dao.findAll();
  15. for(int i=0;i<list.size();i++) {//遍历list
  16. User user=list.get(i);
  17. System.out.println("username:"+user.getUsername());
  18. System.out.println("password:"+user.getPassword());
  19. }
  20. }
  21. @Test
  22. void testInsertElement() {
  23. UserDao dao=new UserDaoImpl();
  24. User people=new User();
  25. people.setUsername("hhhhh");
  26. people.setPassword("66666");
  27. dao.insertElement(people);
  28. }
  29. }

servlet类
LoginServlet.java
  1. package com.ningxiaojian.web.control;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import com.ningxiaojian.domain.User;
  10. import com.ningxiaojian.service.UserService;
  11. import com.ningxiaojian.service.impl.UserServiceImpl;
  12. @WebServlet("/LoginServlet")
  13. public class LoginServlet extends HttpServlet {
  14. private static final long serialVersionUID = 1L;
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. request.setCharacterEncoding("UTF-8");//解决请求乱码(post)
  17. response.setCharacterEncoding("UTF-8");//解决响应乱码,下面要以字符流输出(若字节流输出则要再次编码)
  18. String username=request.getParameter("username");
  19. String password=request.getParameter("password");
  20. String sign=request.getParameter("sign");
  21. PrintWriter out=response.getWriter();
  22. //把传来的数据封装进javabean中
  23. User user=new User();
  24. user.setUsername(username);
  25. user.setPassword(password);
  26. UserService service=new UserServiceImpl();
  27. if("1".equals(sign)) {//登录操作(设置了一个标记)
  28. String loginInfo=service.checkLogin(user);
  29. out.print(loginInfo);
  30. }
  31. else if("2".equals(sign)) {//注册操作
  32. String registerInfo=service.register(user);
  33. out.print(registerInfo);
  34. }
  35. System.out.println(username);//在控制台输出
  36. System.out.println(password);
  37. System.out.println(sign);
  38. }
  39. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  40. doGet(request, response);
  41. }
  42. }

service接口层
UserService.java
  1. package com.ningxiaojian.service;
  2. import com.ningxiaojian.domain.User;
  3. public interface UserService {
  4. //查验登录
  5. public String checkLogin(User user);
  6. //注册用户
  7. public String register(User user);
  8. }

service实现层,服务端的主要逻辑
UserServiceImpl.java
  1. package com.ningxiaojian.service.impl;
  2. import java.util.List;
  3. import com.ningxiaojian.dao.UserDao;
  4. import com.ningxiaojian.dao.impl.UserDaoImpl;
  5. import com.ningxiaojian.domain.User;
  6. import com.ningxiaojian.service.UserService;
  7. public class UserServiceImpl implements UserService {
  8. UserDao dao=new UserDaoImpl();
  9. /*
  10. * 主要的逻辑实现
  11. */
  12. @Override
  13. public String checkLogin(User user) {
  14. List<User> list = dao.findAll();
  15. for(int i=0;i<list.size();i++) {//遍历集合
  16. User user2=list.get(i);
  17. if(user2.getUsername().equals(user.getUsername()) && user2.getPassword().equals(user.getPassword())) {
  18. return "登录成功";
  19. }
  20. }
  21. return "登录失败,密码输入错误";
  22. }
  23. @Override
  24. public String register(User user) {
  25. List<User> list = dao.findAll();
  26. for(int i=0;i<list.size();i++) {
  27. User user2=list.get(i);
  28. if(user2.getUsername().equals(user.getUsername())) {
  29. return "注册失败,该用户名已存在!";
  30. }
  31. }
  32. dao.insertElement(user);
  33. return "注册成功";
  34. }
  35. }

以上就是全部的代码,每句代码都会有详细的解释

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/705051
推荐阅读
相关标签
  

闽ICP备14008679号