JavaWeb 登录示例

一、示例

        为了对Javaweb中的JSP、Servlet以及Listener和Filter进行简单的总结,创建一个简单的只有登录和注册的小项目,项目采用MVC结构并结合了MyBatis进行简单的数据库操作。项目效果示例如下:

登录页面:

 登录时账号或密码错误:

 注册页面:

 二、实现

2.1 Maven依赖:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- 引入MyBatis -->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
    <!--导入数据库驱动,mysql 8.0.16 版本-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</version>
    </dependency>
    <!--日志-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.12</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>
    <!-- jstl标签库 -->
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
  </dependencies>

 2.2 mybatis-config.xml及SqlSessionFactory

         项目中使用了Mybatis作为持久层,因此需要xml配置文件进行配置,并且需要SqlSessionFactory对象,以便获取SqlSession用以操作数据库。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

    <typeAliases>
        <package name="com.wyf.dao.mybatis.model"/>
    </typeAliases>

<!--    <typeHandlers>-->
<!--        <typeHandler-->
<!--                javaType="com.wyf.mybaties.type.Enabled"-->
<!--                handler="com.wyf.mybaties.type.EnabledTypeHandler"/>-->
<!--    </typeHandlers>-->

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC">
                <property name="" value=""/>
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/devicetest?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.wyf.dao.mybatis.mapper" />
    </mappers>
</configuration>

        使用Mybatis,必然要有SqlSessionFactory类,此处使用ServletContextListener上下文参数监听者,在Context参数创建的时候,对SqlSessionFactory类进行初始化。如下BaseMapperTest类用于初始化创建SqlSessionFactory

public class BaseMapperTest {
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 使用xml配置文件,初始化SqlSessionFactory
     */
    public static void init(String config){
        try{
            Reader reader= Resources.getResourceAsReader(config);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }

    /**
     * 由SqlSessionFactory工厂对象,生产SqlSession
     * @return
     */
    public static SqlSession getSqlSession (){
        return sqlSessionFactory.openSession();
    }
}

        通过部署监听者MyServletContextListener类,在上下文参数Context初始化的时候,调用BaseMapperTest类的init()方法,实现对SqlSessionFactory的初始化。

/**
 * 上下文初始化参数监听者
 */
public class MyServletContextListener implements ServletContextListener {
    /**
     * 参数初始化
     * @param servletContextEvent
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //由事件得到ServletContext
        ServletContext sc = servletContextEvent.getServletContext();
        String config = sc.getInitParameter("config"); //获取ServletContext初始参数
        BaseMapperTest.init(config); //上下文初始化参数的时候,使用xml配置文件,初始化SqlSessionFactory
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

2.3 Model

2.3.1 Dao操作

         使用Mybatis,需要将具体的sql语句入mapper.xml文件中,如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.wyf.dao.mybatis.mapper.UserMapper">
    <resultMap id="userMap" type="com.wyf.dao.mybatis.model.User">
        <id property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <result property="userPassword" column="user_password"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <!-- select查询 -->
    <select id="selectById" resultMap="userMap">
        select * from  `user` where id = #{id}
    </select>

    <!-- insert数据插入 -->
    <insert id="insert">
        insert into `user`(
            user_name, user_password, create_time)
        values(#{userName}, #{userPassword}, #{createTime, jdbcType=TIMESTAMP})
    </insert>

    <select id="selectUser" resultType="long">
        SELECT COUNT(*) from `user` WHERE user_name=#{userName} AND user_password=#{userPassword};
    </select>

</mapper>

        对应mapper.xml文件的映射接口如下所示:

/**
 * 接口文件
 */
public interface UserMapper {
    /**
     * 新增用户
     *
     * @param sysUser
     * @return 返回影响行数
     */
    int insert(User sysUser);

    /**
     * 通过ID查询用户
     * @param id
     * @return
     */
    User selectById(int id);

    /**
     * 查询符合登录条件的用户数
     * @return
     */
    long selectUser(User sysUser);
}

        如下为对应数据库user表格的实体类: 

/**
 * 对应数据库user表格的实体类
 */
public class User {
    private int id;
    private String userName;
    private String userPassword;
    private Date createTime;

    public int getId() {
        return id;
    }

    public String getUserName() {
        return userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

}

 2.3.2 Service操作

        service操作中包含两个类,分别对应于登录操作以及注册操作,如下所示:

/**
 * 用户登录
 */
public class LoginUser {
    private String userName;
    private String userPassword;

    public LoginUser(String userName,String userPassword){
        this.userName = userName;
        this.userPassword = userPassword;
    }
    /**
     * 登录判断
     * @return
     */
    public User login(){
        User result = null;
        SqlSession sqlSession = BaseMapperTest.getSqlSession(); //获取数据库操作对象
        try{
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setUserName(userName);
            user.setUserPassword(userPassword);
            //将新建的对象插入数据库中,返回值result 是执行的SQL影响的行数
            long res = userMapper.selectUser(user);
            if(res>0){
                result = user;
            }else{
                result = null;
            }
        } catch(Exception e){
            e.printStackTrace();
        } finally{
            sqlSession.close();   //关闭链接
        }
        return result;
    }
}
/**
 * 用户注册
 */
public class RegistUser {

    private String userName;
    private String userPassword;

    public RegistUser(String userName, String userPassword){
        this.userName = userName;
        this.userPassword = userPassword;
    }

    /**
     * 注册
     * @return
     */
    public int register(){
        int res = 0;
        SqlSession sqlSession = BaseMapperTest.getSqlSession();
        try{
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setUserName(userName);
            user.setUserPassword(userPassword);
            user.setCreateTime(new Date());
            //将新建的对象插入数据库中,返回值result 是执行的SQL影响的行数
            res = userMapper.insert(user);
        } catch(Exception e){
            res = -1;
            e.printStackTrace();
        } finally{
            sqlSession.commit();  //提交操作结果
            sqlSession.close();   //关闭链接
        }
        return res;
    }

}

        此处应该将SqlSession 及响应的操作封装到DAO层,以便更好的体现出MVC的优势。但是作为一个Javaweb示例程序,没有那么严谨,真正的项目应对Dao层及Service层有明确的界限。

2.4 View页面

        首先需要有一个JSP页面,项目中的页面都属于View层。如下,是登录页面:

<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <style>
        .h_title{position: relative;display: inline-block;}
        .box_div{
            width: 100%;
        }
        .box_main{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
            width: 60%;
            min-width: 700px;
            box-shadow: 0 0 30px #322f2f;
        }
        .box_main_right{
            width: 50%;
            height:450px;
            float: left;
            position: relative;
        }
        .box_form{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
        }
    </style>
    <title>Title</title>
</head>
<body style="text-align: center">

<div class="box_div">
    <div class="box_main">
        <div style="width:50%;height:450px;float: left;background: blueviolet">
            <br>
            <h2 class="h_title">智&nbsp;能&nbsp;仪&nbsp;表&nbsp;设&nbsp;备&nbsp;管&nbsp;理</h2>
        </div>
        <div class="box_main_right">
            <div class="box_form">
                <div style="width: 300px">
                    <h3 style="float: left">登&nbsp;&nbsp;录</h3>
                    <c:if test="${not empty message}">
                        <div style="width: 100%;height: 40px;clear: left;margin-bottom: 15px;background: rgba(252,158,158,0.3);border-radius: 5px">
                            <P style="font-size: 17px;color: #8a1717;line-height: 40px;">账号或密码错误!</P>
                        </div>
                    </c:if>
                </div>
                <form action="login.do"  method="post" style="width: 300px;">
                    <input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="submit"value="登&nbsp;&nbsp;录" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
                </form>
                <form action="register.jsp" style="width: 300px">
                    <input type="submit" value="新用户注册" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
                </form>
            </div>
        </div>
    </div>
</div>

</body>
</html>

注册页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <style>
        .h_title{position: relative;display: inline-block;}
        .box_div{
            width: 100%;
        }
        .box_main{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
            width: 60%;
            min-width: 700px;
            box-shadow: 0 0 30px #322f2f;
        }
        .box_main_right{
            width: 50%;
            height:450px;
            float: left;
            position: relative;
        }
        .box_form{
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50%,-50%);
        }
    </style>
    <title>Title</title>
</head>
<body style="text-align: center">

<div class="box_div">
    <div class="box_main">
        <div style="width:50%;height:450px;float: left;background: blueviolet">
            <br>
            <h2 class="h_title">智&nbsp;能&nbsp;仪&nbsp;表&nbsp;设&nbsp;备&nbsp;管&nbsp;理</h2>
        </div>
        <div class="box_main_right">
            <div class="box_form">
                <div style="width: 300px">
                    <h3 style="float: left">注&nbsp;&nbsp;册</h3>
                </div>
                <form action="register.do"  method="post" style="width: 300px;">
                    <input type="text" name="name" value="" placeholder="用户名" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="password" name="pwd" value="" placeholder="密码" style="width: 100%;height: 40px;border-radius: 5px"><br><br>
                    <input type="submit"value="立即注册" name="login" style="width: 100%;height: 35px;background: orange;color: white;font-size: 17px;border-radius: 5px">
                </form>
                <form action="index.jsp" style="width: 300px">
                    <input type="submit" value="返回登录" style="width: 100%;height: 35px;background: deepskyblue;color:white;font-size: 17px;border-radius: 5px">
                </form>
            </div>
        </div>
    </div>
</div>

</body>
</html>

2.5 Controller(Servlet)

/**
 * 创建一个简单的Servlet类
 */
public class LoginServlet extends HttpServlet {

    /**
     * post请求
     * @param request
     * @param response
     * @throws IOException
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        PrintWriter out=response.getWriter();
        //获取请求携带的参数
        String userName = request.getParameter("name");
        String userPassword = request.getParameter("pwd");
        LoginUser loginUser = new LoginUser(userName,userPassword);
        User user = loginUser.login();
        if(user!=null){
            //登录成功
            request.getSession().setAttribute("user",user);  //设置会话属性,会话属性与请求属性的主要区别在范围
//            request.setAttribute("message", "欢迎用户"+userName); //向request域中放置信息
//            request.getRequestDispatcher("/main.jsp").forward(request, response);//转发到成功页面
            response.setContentType("text/html");
            response.sendRedirect("main.jsp");
        }else{
            //验证失败
            request.setAttribute("message", "用户名或密码错误,请重试!"); //向request域中放置信息
            request.getRequestDispatcher("/index.jsp").forward(request, response);//转发到成功页面
        }
    }
}
/**
 * 注册页面的servlet
 */
public class RegisterServlet extends HttpServlet {
    /**
     * post请求
     * @param request
     * @param response
     * @throws IOException
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //获取jsp页面传递到服务器的参数
        String userName = request.getParameter("name");
        String usePassword = request.getParameter("pwd");

        RegistUser registUser = new RegistUser(userName,usePassword);
        if(registUser.register()>0){
            //注册成功
            request.getRequestDispatcher("/index.jsp").forward(request,response);
        }else{
            //注册失败
            request.setAttribute("message","注册失败");
            request.getRequestDispatcher("/index.jsp").forward(request,response);
        }
    }
}

        为了对登录进行检查,我们使用Filter过滤器,对所有请求进行检查,以判断是否登录。

/**
 * 登录检查
 */
public class LoginCheckFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //初始化
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //获取资源请求路径
        String uri = request.getRequestURI();
        String[] loginUri = {"/index.jsp","/register.jsp","/login.do","/register.do","/"};
        //判断是否包含登录相关请求
        for(String path:loginUri){
            if (uri.endsWith(path)) {
                filterChain.doFilter(request,response);
                return;
            }
        }
        //请求的url不在特定uri之内
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("user") == null) {
            response.setContentType("text/html");
            response.sendRedirect("index.jsp");
        }else{
            filterChain.doFilter(request,response);
        }
    }

    @Override
    public void destroy() {
        //销毁
    }
}

        Filter过滤器有很多应用,如下所示,对编码进行设置:

public class EncodingFilter implements Filter {

    private String encoding = "UTF-8"; // 默认编码UTF-8

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 如果用户配置了编码,则将encoding设置为用户编码
        if(filterConfig.getInitParameter("ENCODING")!=null){
            encoding = filterConfig.getInitParameter("ENCODING");
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 设置请求与响应的编码
        servletRequest.setCharacterEncoding(encoding);
        servletResponse.setCharacterEncoding(encoding);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        encoding = null;
    }
}

2.6 web.xml

<!-- 部署描述文件 -->
<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!-- 上下文参数 -->
  <context-param>
    <param-name>config</param-name>
    <param-value>mybatis-config.xml</param-value>
  </context-param>

  <!-- 声明过滤器 -->
  <filter>
    <filter-name>Encoding</filter-name>
    <filter-class>com.wyf.filter.EncodingFilter</filter-class>
    <init-param>
      <param-name>ENCODING</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter>
    <filter-name>LoginCheck</filter-name>
    <filter-class>com.wyf.filter.LoginCheckFilter</filter-class>
  </filter>

  <!-- 过滤器映射 -->
  <filter-mapping>
    <filter-name>Encoding</filter-name>
    <url-pattern>/*</url-pattern> <!-- url-pattern 元素定义了哪些web应用资源要使用该过滤器 --> <!-- /*是对所有的文件进行拦截 -->
  </filter-mapping>
  <filter-mapping>
    <filter-name>LoginCheck</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 注册监听者 -->
  <listener>
    <listener-class>com.wyf.listener.MyServletContextListener</listener-class>
  </listener>

  <!-- servlet部署 -->
  <servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>com.wyf.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>register</servlet-name>
    <servlet-class>com.wyf.servlet.RegisterServlet</servlet-class>
  </servlet>
  <!-- 将servlet与url映射 -->
  <servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/login.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>register</servlet-name>
    <url-pattern>/register.do</url-pattern>
  </servlet-mapping>
</web-app>

三、结束

        本文主要以一个登录注册操作,对Javaweb的基础内容,servlet、jsp、session、listener、Filter以及MVC结构进行简单的总结。

项目源码:https://download.csdn.net/download/sssxlxwbwz/85064123

  • 7
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值