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

下面是“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日

相关文章

  • Java线程通信之wait-notify通信方式详解

    针对题目“Java线程通信之wait-notify通信方式详解”的完整攻略,以下是详细讲解。 标题 在文章中,应该清晰地使用标题来分隔内容,以便读者可以快速浏览和导航整篇文章。 介绍 在这个部分,我们将简要介绍Java中的线程通信和wait-notify通信方式。线程通信是指多个线程之间的协作和通信,为了互相通信和协调,线程需要一些机制,而wait-noti…

    Java 2023年5月19日
    00
  • 关于Java for循环的正确用法介绍

    关于Java for循环的正确用法介绍 循环是Java中非常重要的一种语句。for循环是循环语句中最为常用和灵活的一种,它可以重复执行一段代码,在Java语言中,for循环的语法格式如下: for (初始化表达式; 布尔表达式; 更新表达式) { // 循环体 } 初始化表达式:初始化表达式在循环开始前执行,而且只会执行一次。这里我们一般做循环变量的初始化操…

    Java 2023年5月26日
    00
  • Java线程死锁代码详解

    这里我给你提供一份“Java线程死锁代码详解”的攻略,希望能对你有所帮助。 背景介绍 线程死锁在多线程环境下是非常常见的情况,而解决线程死锁也非常困难,因此需要我们对线程死锁有一个深入的了解。本文将详细讲解Java线程死锁的原因、示例以及如何解决死锁。 什么是线程死锁? 当两个或更多的线程互相持有对方所需要的资源,同时等待对方释放资源,就会出现线程死锁。可以…

    Java 2023年5月24日
    00
  • spring boot多数据源动态切换代码实例

    下面将为您详细讲解如何实现在Spring Boot应用中实现多数据源动态切换,并提供两个示例。 一、前置条件 在开始编写代码之前,需要满足以下条件: 确保已经正确配置了多个数据源,这些数据源需要连接的数据库表结构和数据内容都应当是相同的; 当前应用中必须已经引入了相关依赖,这里采用Spring Boot 2.x版本为例: <dependencies&g…

    Java 2023年5月20日
    00
  • Java Scala之面向对象

    Java Scala之面向对象:完整攻略 什么是面向对象 面向对象(Object Oriented Programming,简称OOP)是一种编程范式,主要思想是将数据和对数据的相关操作封装在一个单元中,形成对象。通过对对象的定义、组合和继承等机制实现程序的可扩展性、灵活性和可维护性。 面向对象的三大特征 封装(Encapsulation) 封装就是将程序中…

    Java 2023年5月26日
    00
  • 一文理解kafka rebalance负载均衡

    一文理解Kafka Rebalance负载均衡 在Kafka中,消费者组(Consumer Group)中的多个消费者(Consumer)会协同消费一个或多个Topic的分区(Partition)。消费者组通过Partition的分配策略来确定每个消费者负责消费哪些分区。当新的消费者加入或退出消费者组时,需要重新进行分区分配,这个过程被称为Rebalance…

    Java 2023年5月20日
    00
  • Java从服务器上获取时间动态显示在jsp页面实现思路

    获取服务器上的时间并动态地显示在 JSP 页面上可以通过以下步骤来实现: 在 JSP 页面上引入 Java 提供的日期处理类库 java.util.Date 通过 Java 代码获取当前的时间并将其转化为字符串格式 在 JSP 页面上使用 JavaScript 定时刷新页面内容,动态显示时间 以下是具体的实现步骤和示例代码: 引入 Date 类库 在 JSP…

    Java 2023年5月20日
    00
  • Spring Batch批处理框架操作指南

    Spring Batch批处理框架操作指南 简介 Spring Batch是针对于处理海量数据的批处理框架,它通过创建批处理作业(Job)来完成数据的读取、处理和写入输出的操作。本指南为您提供Spring Batch的完整操作指南。 原理 Job: 对整个批处理过程进行定义与配置。 Step: 是Job的一部分,代表一个特定的处理阶段。 ItemReader…

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