基于Servlet/Filter/JDBC的简易登陆注册

221 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

总述

本文主要总结近期做的一个小案例,该案例是一个简易的登录注册java后端,顺便对JDBC、Filter、axios、Servlet等知识做一个回顾与复习

效果演示

简单演示一下登陆功能。
登录注册简易界面

后端接收

密码错误时

JDBC部分

navicat构建数据库

  • step1:新建连接,连接到mysql
  • step2:创建数据库及user数据表
  • step3:设计表,新增id、username、password字段,如下。

JDBC连接数据库

代码实现:

 public Connection config() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://47.98.177.122:3305/my_db_01";
        String url = "jdbc:mysql://127.0.0.1:3306/my_db_01";
        String username = "root";
        String password = "admin1234";
        Connection conn = DriverManager.getConnection(url,username,password);
        return conn;
    }

代码讲解:
(1)本部分主要用于数据库的连接配置,并抛出Connection连接对象,方便模块化处理。
(2)上述代码Class.forName是在导数据库Driver驱动,具体路径见下图:

在5版本以上,已经不需要我们程序员自己再去导入这个驱动了,jdbc已经为我们写好。
(3)通过DriverManager(驱动管理器类)的getConnection方法连接数据库并返回一个Connection对象接收。最后向外共享这个连接对象conn。

JDBC数据库查询

代码实现:

 public boolean queryusername(String username1) throws Exception{
        SqlConfig sql = new SqlConfig();
        Connection conn = sql.config();
        String sqlstr = "select username from user";
        //Connection conn = config();
        Statement stmt = (Statement) conn.createStatement();
        ResultSet rs = stmt.executeQuery(sqlstr);
        while (rs.next()){
         //获取数据 getXxx()
            String name = rs.getString("username");
            //判断表单提交过来的用户名,是否在数据库中已存在
            //此部分修改主要是便于注册功能的实现
            if(username1.equals(name)){
                System.out.println(name);
                return false;
            }
        }
        rs.close();
        stmt.close();
        conn.close();
        return true;
    }

代码讲解:
(1)该部分代码主要实现数据库中username的查询,查询到与传递过来的username有相同的,就返回一个false,表示用户注册出现用户名重复的情况,反之亦然。
(2)该部分用一个boolearn类型作为返回值,在查询部分实现了注册功能逻辑的判断。
(3)首先是上一部分的连接对象conn

 SqlConfig sql = new SqlConfig();
 Connection conn = sql.config();

定义sql查询语句sqlstr,查询username字段。代码中statement对象的作用就是来执行SQL语句。因此需要先获取statement对象。

Statement stmt = (Statement) conn.createStatement();

JDBC针对不同类型SQL语句有不同的方法:

  • executeUpdate方法用于执行DDL、DML语句,返回一个int类型(影响的行数)。
  • executeQuery方法用于执行DQL语句,返回单个ResultSet对象(结果集)。
    结果集中获取数据的方法:
    boolean next() 将光标从当前位置向前移动一行 判断当前行是否为有效行方法返回值说明:
    true : 有效行,当前行有数据 false : 无效行,当前行没有数据
    xxx getXxx(参数):获取数据 xxx : 数据类型;如: int getInt(参数) ;String getString(参 数) 参数 int类型的参数:列的编号,从1开始 String类型的参数: 列的名称
    具体用法:
while (rs.next()){ //6.2 获取数据 getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("username");
            System.out.println(id);
            System.out.println(name); 
        }

最后要关闭资源,释放连接。

JDBC数据库插入

代码实现

 public boolean Insertdata(String username1,String password1) throws Exception{
        SqlConfig sql = new SqlConfig();
        String sqlstr = "INSERT INTO user(username,password) VALUES (?,?)";
        Connection conn = sql.config();
        //Connection conn = config();
        // Statement stmt = (Statement) conn.createStatement();
        PreparedStatement pstmt = conn.prepareStatement(sqlstr);
        pstmt.setString(1,username1);
        pstmt.setString(2,password1);
        int count = pstmt.executeUpdate();
        if(count > 0){
            System.out.println("数据插入成功");

        }else{
            System.out.println("username:"+username1+","+"password:"+password1);
            System.out.println("数据插入失败");
            return false;
        }
        pstmt.close();
        conn.close();
        return true;
    }

代码讲解:
(1)这里的boolearn类型返回值与上一部分作用大致相同,主要介绍查询与增删改的区别处。
(2)这里的sql语句中多了两个问号,主要作用是占位,占位符。statement不能执行有占位符的sql语句,所以这里换了PrepareStatement对象。
(3)PrepareStatement对象主要作用是预编译SQL语句并执行,预防SQL注入问题。SQL注入是通过操作输入来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。

        PreparedStatement pstmt = conn.prepareStatement(sqlstr);
        pstmt.setString(1,username1);
        pstmt.setString(2,password1);
        int count = pstmt.executeUpdate();

可以对比statement,用法相似。要注意的是conn.prepareStatement函数是需要填入要执行的sql语句的,而在执行处不需要填写sql语句,这是与statement使用的一个区分。

事务管理

另外补充一点事务管理的知识。

MYSQL默认自动帮我们提交事务,当我们执行sql语句的时候,处理完往往会自动提交。
我们需要通过设置自动提交为false,来手动开启事务。具体使用上述代码已写的很清楚。

servlet

maven工程的创建

步骤如下图:

注意:
第三步:m1用jdk8一定要用zulu的,不然会报错的。
第四步:web工程一定要是maven--------webapp

这里要勾选上,不然新建里面没有servlet的,比较麻烦。

基于servlet的java文件


新建好的文件基本就长这个样子,1的位置需要自己写,里面的路径是访问的路径。通过post或get访问这条路径会触发响应的doPost和doGet函数。

servlet项目打war包

在run中选取Edit Configuration,添加tomcat,然后对tomcat进行配置。

tomcat配置
Application server处填你的tomcat。

在Deployment这里把你的项目打成war包。
项目运行就在下面的URL处。

Filter

概述

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
在访问到这些资源之前可以使过滤器拦截来下,也就是说在访问资源之前会先经过 Filter。

执行流程:

拦截路径
表示 Filter 会对请求的哪些资源进行拦截,使用 @WebFilter("拦截路径") 注解进行配置。如:拦截路径有如下四种配置方式:
拦截具体的资源:/index.jsp:只有访问index.jsp时才会被拦截
目录拦截:/user/:访问/user下的所有资源,都会被拦截
后缀名拦截:
.jsp:访问后缀名为jsp的资源,都会被拦截
拦截所有:/*:访问所有资源,都会被拦截

Filter就是创建一个类去实现javax.servlet包下的Filter接口。
该接口下主要有三个方法:init、doFilter、destory,我们写的主要拦截代码在doFilter中。

Filter中请求体数据的获取

请求体中数据不能直接通过getParameter()方法获得,需要用getReader来获得,该方法返回一个BufferedReader对象,然后使用readline来获取具体数据。

BufferedReader body =   servletRequest.getReader();
String message = body.readLine();

Json字符串转java对象:

User userinfo = JSON.parseObject(message, User.class);
System.out.println(userinfo);