Java web含验证码及权限登录实例代码

yizhihongxing

下面是“Java web含验证码及权限登录实例代码”的完整攻略:

准备工作

在开始编写代码前,我们需要准备一些工作:

  1. 确保已经安装好Java开发环境,并且熟悉Java web开发基础知识。
  2. 安装一个Web服务器,比如Tomcat。
  3. 准备好一个关系数据库,比如MySQL。

功能概述

我们这里实现的是一个带有验证码和权限登录控制的Java Web应用。功能包括:

  1. 用户注册
  2. 用户登录
  3. 权限控制
  4. 验证码生成和校验

技术选型

我们使用以下技术来实现这个应用:

  1. Spring Framework: 用于依赖注入、控制反转和AOP等功能。
  2. Spring MVC: 基于Spring Framework的MVC框架。
  3. Spring Security: 提供权限控制和安全性的框架。
  4. MyBatis: 用于操作关系数据库。
  5. Maven: 用于管理项目依赖。

详细步骤

下面是具体的步骤:

1. 创建Maven项目

首先,我们需要创建一个Maven项目。在项目根目录下,执行以下命令:

mvn archetype:generate -DgroupId=com.example -DartifactId=demo -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

该命令会创建一个名为demo的Maven项目。

2. 添加依赖

接下来,我们需要添加依赖。在pom.xml文件中添加以下依赖:

<dependencies>
  <!-- Spring Framework -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.12.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.12.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.12.RELEASE</version>
  </dependency>
  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>5.4.1</version>
  </dependency>
  <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>5.4.1</version>
  </dependency>

  <!-- MyBatis -->
  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
  </dependency>
  <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.6</version>
  </dependency>

  <!-- Servlet and JSP API -->
  <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
  </dependency>
  <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
      <scope>provided</scope>
  </dependency>

  <!-- JSTL -->
  <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
  </dependency>

  <!-- jBCrypt for password hashing -->
  <dependency>
      <groupId>org.mindrot</groupId>
      <artifactId>jbcrypt</artifactId>
      <version>0.4</version>
  </dependency>

  <!-- MySQL -->
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.23</version>
  </dependency>

  <!-- Commons Lang for generating random strings -->
  <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.12.0</version>
  </dependency>

  <!-- Google Guava for generating random numbers -->
  <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>30.0-jre</version>
  </dependency>
</dependencies>

这里我们使用了Spring Framework和Spring Security来实现权限控制,MyBatis来操作关系数据库,MySQL作为关系数据库,jBCrypt用于密码哈希,Commons Lang和Google Guava用于生成随机字符串和数字等。

3. 配置Spring和MyBatis

下一步,我们需要添加Spring和MyBatis的配置文件。在src/main/resources目录下,创建一个名为applicationContext.xml的XML文件,然后添加以下内容:

<!-- 数据库连接信息 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/demo?useSSL=false&amp;serverTimezone=UTC&amp;characterEncoding=UTF-8" />
  <property name="username" value="root" />
  <property name="password" value="root" />
</bean>

<!-- MyBatis SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="mapperLocations" value="classpath:mapper/*.xml" />
</bean>

<!-- MyBatis MapperScanner -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="com.example.demo.dao" />
</bean>

这里我们配置了MySQL的连接信息,并且创建了一个SqlSessionFactoryBean和一个MapperScannerConfigurer,用于操作关系数据库。

接下来,我们需要在web.xml文件中配置Spring的DispatcherServlet,以及配置Spring Security。在src/main/webapp/WEB-INF目录下,创建一个名为spring-security.xml的XML文件,添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
    xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- 放行静态资源 -->
    <b:http pattern="/css/**" security="none" />
    <b:http pattern="/js/**" security="none" />
    <b:http pattern="/images/**" security="none" />

    <!-- 定义用户角色 -->
    <b:authentication-manager>
        <b:authentication-provider>
            <b:user-service>
                <!-- 定义角色 -->
                <b:user name="admin" password="{bcrypt}$2a$10$B8fn7t5ZrJMGt6.8er8d1e9Uh5oK.57pn7Qd8M9.VXBKfx6nkUW6e" authorities="ROLE_ADMIN" />
                <b:user name="user" password="{bcrypt}$2a$10$B8fn7t5ZrJMGt6.8er8d1e9Uh5oK.57pn7Qd8M9.VXBKfx6nkUW6e" authorities="ROLE_USER" />
            </b:user-service>
        </b:authentication-provider>
    </b:authentication-manager>

    <!-- 定义访问规则 -->
    <http auto-config="true" access-denied-page="/login?error=true">
        <!-- 配置登录页面 -->
        <form-login login-page="/login" default-target-url="/index" authentication-failure-url="/login?error=true" />
        <!-- 配置注销 -->
        <logout logout-success-url="/logout" />
        <!-- 定义授权规则 -->
        <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
        <intercept-url pattern="/user/**" access="ROLE_USER" />
        <intercept-url pattern="/common/**" access="ROLE_ADMIN,ROLE_USER" />
        <!-- 配置访问拒绝页面 -->
        <access-denied-handler error-page="/403" />
    </http>

</b:beans>

在这个配置文件中,我们定义了用户角色和访问规则,并且配置了登录页面、注销和访问拒绝页面。

4. 编写Java类和SQL文件

接下来,我们需要编写Java类和SQL文件。

首先,我们来编写一个User类,代表一个用户。在src/main/java/com/example/demo/entity目录下,创建一个名为User.java的类文件,添加以下内容:

package com.example.demo.entity;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String role;

    // getters and setters
}

这个类代表了一个用户的基本信息,包括id、username、password和role字段。

接着,我们来编写一个UserDao类,用于操作数据库中的用户表。在src/main/java/com/example/demo/dao目录下,创建一个名为UserDao.java的接口文件,添加以下内容:

package com.example.demo.dao;

import com.example.demo.entity.User;

public interface UserDao {
    User getUserByUsername(String username);
    int insertUser(User user);
}

这个接口包含了两个方法,一个用于根据用户名获取用户信息,一个用于插入一个用户到数据库中。

接下来,我们来实现UserDao接口。在src/main/java/com/example/demo/dao/impl目录下,创建一个名为UserDaoImpl.java的类文件,添加以下内容:

package com.example.demo.dao.impl;

import com.example.demo.dao.UserDao;
import com.example.demo.entity.User;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private SqlSessionTemplate sqlSession;

    @Override
    public User getUserByUsername(String username) {
        return sqlSession.selectOne("UserMapper.getUserByUsername", username);
    }

    @Override
    public int insertUser(User user) {
        return sqlSession.insert("UserMapper.insertUser", user);
    }
}

这个类实现了UserDao接口,并且使用了MyBatis的SqlSessionTemplate来操作数据库。

接下来,我们来编写一个UserController类,用于控制用户的注册和登录。在src/main/java/com/example/demo/controller目录下,创建一个名为UserController.java的类文件,添加以下内容:

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class UserController {
    @Autowired
    private Producer captchaProducer = null;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/captcha.jpg", method = RequestMethod.GET)
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");

        String capText = captchaProducer.createText();
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);

        ModelAndView mav = new ModelAndView("captcha");

        mav.addObject("captchaText", capText);

        return mav;
    }

    @GetMapping("/login")
    public String login(Model model, @RequestParam(name = "error", required = false) boolean error) {
        if (error) {
            model.addAttribute("errorMsg", "用户名或密码错误");
        }
        return "login";
    }

    @PostMapping("/login")
    public String doLogin(HttpServletRequest request, String username, String password, String captcha) {
        String sessionCaptcha = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (!captcha.equalsIgnoreCase(sessionCaptcha)) {
            return "redirect:/login?error=true";
        }
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authentication = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return "redirect:/index";
    }

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String register(Model model) {
        model.addAttribute("user", new User());
        return "register";
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String doRegister(User user, String confirmPassword, String captcha, HttpServletRequest request) {
        if (!captcha.equalsIgnoreCase((String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY))) {
            return "redirect:/register";
        }

        User existUser = userService.findByUsername(user.getUsername());
        if (existUser != null) {
            return "redirect:/register?error=username exists";
        }

        if (!user.getPassword().equals(confirmPassword)) {
            return "redirect:/register?error=password not match";
        }

        String hashedPassword = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(hashedPassword);
        user.setRole("ROLE_USER");

        userService.save(user);

        return "redirect:/login";
    }

    @GetMapping("/index")
    public String index() {
        return "index";
    }

    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }

    @GetMapping("/user")
    public String user() {
        return "user";
    }

    @RequestMapping("/403")
    public String accessDenied() {
        return "403";
    }
}

在这个类中,我们使用了Spring Security的AuthenticationManager和Authentication对象来对用户进行认证和授权,使用了Google Kaptcha来生成和校验验证码,使用了BCryptPasswordEncoder来对用户密码进行哈希,并且编写了用户注册和登录的逻辑,实现了权限控制。

接下来,我们需要编写SQL文件,定义通过用户名获取用户信息和插入用户到数据库中的SQL。在src/main/resources/mapper目录下,创建一个名为UserMapper.xml的XML文件,添加以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.example.demo.dao.UserDao">

  <select id="getUserByUsername" resultType="com.example.demo.entity.User"
          parameterType="java.lang.String">
    SELECT * FROM users
    WHERE username=#{username}
  </select>

  <insert id="insertUser" parameterType="com.example.demo.entity.User">
    INSERT INTO users(username, password, role) VALUES (
      #{username}, #{password}, #{role}
    )
  </insert>

</mapper>

这个文件会被MyBatis自动扫描到并且用于操作数据库。

5. 编写HTML模板和CSS文件

最后,我们需要编写HTML模板和CSS文件。在src/main/webapp目录下,创建以下目录和文件:

  • css/style.css: 样式文件
  • images/bg.jpg: 登录页面的背景图片
  • WEB-INF/views/captcha.jsp: 生成的验证码图片
  • WEB-INF/views/index.jsp: 首页
  • WEB-INF/views/login.jsp: 登录页面
  • WEB-INF/views/register.jsp: 注册页面
  • WEB-INF/views/admin.jsp: 管理员页面
  • WEB-INF/views/user.jsp: 普通用户页面
  • WEB-INF/views/403.jsp: 拒绝访问页面

其中,在WEB-INF/views/login.jsp页面中,我们需要添加验证码的展示:

<form action="/login" method="post">
  <div>
    <label>用户名:</label>
    <input type="text" name="username" required>
  </div>
  <div>
    <label>密码:</label>
    <input type="password" name="password" required>
  </div>
  <div>
    <label>验证码:</label>
    <input type="text" name="captcha" required>
  </div>
  <div>
    <img src="${pageContext.request.contextPath}/captcha.jpg" onclick="this.src='${pageContext.request.contextPath}/captcha.jpg?'+Math.random();" />
  </div>
  <div>
    <button type="submit">登录</button>
  </div>
</form>

点击

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java web含验证码及权限登录实例代码 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • Angular.js中ng-include用法及多标签页面的实现方式详解

    针对“Angular.js中ng-include用法及多标签页面的实现方式详解”的主题,我来提供完整的攻略。 ng-include用法讲解 在Angular.js中,我们可以使用ng-include指令来实现将一个页面嵌入到另外一个页面的功能。以下是ng-include的使用方法: <!– 在此处加载其他模板文件 –> <div ng-…

    Java 2023年6月15日
    00
  • SpringBoot个性化配置的方法步骤

    Spring Boot 个性化配置的方法步骤 在 Spring Boot 中,我们可以使用个性化配置来覆盖默认的配置。个性化配置可以帮助我们在不修改默认配置的情况下,对应用程序进行自定义配置。在本文中,我们将详细介绍 Spring Boot 个性化配置的方法步骤,并提供两个示例。 方法步骤 以下是 Spring Boot 个性化配置的方法步骤: 创建一个名为…

    Java 2023年5月15日
    00
  • 详解Java中的日期类

    详解Java中的日期类 Java提供了许多用于处理日期和时间的内置类,其中包括日期类、时间类、日历类等。在这些类中,最基础和常用的是日期类java.util.Date和日期格式化类java.text.SimpleDateFormat。 java.util.Date类 java.util.Date类表示了一个时间点,它存储了一个long类型的整数值,该值代表了…

    Java 2023年5月20日
    00
  • SpringBoot2新特性 自定义端点详解

    Spring Boot 2新特性自定义端点详解 Spring Boot 2引入了许多新特性,其中之一是自定义端点。自定义端点是一种用于公开应用程序信息的机制,可以通过HTTP或JMX访问。在本文中,我们将详细介绍Spring Boot 2的自定义端点,并提供两个示例。 自定义端点 Spring Boot 2的自定义端点是通过实现Endpoint接口来实现的。…

    Java 2023年5月15日
    00
  • Java中实现获取路径的方法汇总

    Java中实现获取路径的方法可以使用多种方式,常用的有以下几种: 1. 使用Class.getResource(String path)方法获取资源路径 // 获取classpath下src/main/resources目录下的test.txt文件的URL对象 URL resourceUrl = getClass().getResource("/t…

    Java 2023年6月15日
    00
  • Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析

    下面我来详细讲解“Java,JSP,Servlet获取当前工程路径(绝对路径)问题解析”的完整攻略。 问题描述 在Java Web开发中,有时需要获取当前工程(Web应用)的路径,一般是为了将文件读取到项目中,或者是为了控制输出的文件路径。本文将解决以下两个问题: 如何在Java项目中获取当前工程路径 如何在JSP和Servlet中获取当前工程路径 获取当前…

    Java 2023年6月15日
    00
  • Java StackTraceElement实例代码

    接下来我将为你详细讲解“Java StackTraceElement实例代码”的完整攻略。 什么是StackTraceElement 在Java程序中,当出现异常时,Java虚拟机会在控制台上打印错误堆栈信息,其中包含了程序执行时所调用方法的信息。Java的StackTraceElement类可以获取方法执行的堆栈跟踪信息,包括方法名、文件名、行数等。 语法…

    Java 2023年5月23日
    00
  • layui之数据表格–与后台交互获取数据的方法

    首先,需要在后台构建好返回数据的接口,即后台返回数据应该是一个符合layui表格规范的JSON格式数据。 接下来的步骤是: 引入layui库 在前端页面中,需要引入layui库,以便能够正常使用 layui 提供的数据表格组件。 <!– 引入 layui 相关静态资源 –> <link rel="stylesheet&quot…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部