项目目标:
IDEA中创建一个Maven -》springBoot项目,实现用户登录检验的功能,使用Hibernate对数据进行管理。当用户名、密码和验证码均正确的时候,显示登录成功的信息。
目录
1、项目环境搭建
新建一个springboot项目,选择JPA(hibernate)数据库,在pom文件的依赖如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<!--Spring Boot的核心启动器,包含了自动配置、日志和YAML-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--支持全栈式Web开发,包括Tomcat和spring-webmvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--springboot jpa起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<!--阿里巴巴的json包依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!--注入themleaf的依赖坐标-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
application.properties的配置信息如下:
#DB 添加数据库的连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///db_hibernate?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#spring.jpa.properties.hibernate.hbm2ddl.auto=update
#JPA配置信息
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
#配置themeleaf转发页面的设置
spring.thymeleaf.prefix=classpath:/templates/
2、前台登录页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<div class="row">
<form method="post" action="/loginVerify">
<div class="col-xs-6 pull_left">
<div class="form-group">
用户名:<input class="form-control" type="tel" id="user-name-label" name="user-name-label" placeholder="请输入用户名" maxlength="4">
</div>
</div>
<div class="col-xs-6 pull_left">
<div class="form-group">
密 码:<input class="form-control" type="tel" id="password-label" name="password-label" placeholder="请输入登录密码" maxlength="4">
</div>
</div>
<div class="col-xs-6 pull_left">
<div class="form-group">
验证码:<input class="form-control" type="tel" id="verify_input" name="verify_input" placeholder="请输入验证码" maxlength="4">
</div>
</div>
<div class="col-xs-6 pull_left">
<a href="javascript:void(0);" title="点击更换验证码">
<img id="imgVerify" src="login/getVerify" alt="更换验证码" height="36" width="170" onclick="getVerify(this);">
</a>
</div>
<input type="submit" value="submit"/>
</form>
</div>
</body>
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script>
function getVerify() {
// $("#imgCode").on("click", function() {
$("#imgVerify").attr("src", 'login/getVerify?' + Math.random());//jquery方式
// });
}
</script>
</html>
注意:在引入静态资源包的时候,引入资源的代码块应该放在所有的js代码块前面。如以下代码,放在了js前面。
3、工具类的实现
验证码的工具类,直接使用,不用修改:
package com.songo.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
public class RandomValidateCodeUtil {
public static final String RANDOMCODEKEY= "RANDOMVALIDATECODEKEY";//放到session中的key
private String randString = "0123456789";//随机产生只有数字的字符串 private String
//private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串
//private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串
private int width = 95;// 图片宽
private int height = 25;// 图片高
private int lineSize = 40;// 干扰线数量
private int stringNum = 4;// 随机产生字符数量
private static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class);
private Random random = new Random();
/**
* 获得字体
*/
private Font getFont() {
return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
}
/**
* 获得颜色
*/
private Color getRandColor(int fc, int bc) {
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc - 16);
int g = fc + random.nextInt(bc - fc - 14);
int b = fc + random.nextInt(bc - fc - 18);
return new Color(r, g, b);
}
/**
* 生成随机图片
*/
public void getRandcode(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
// BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0, 0, width, height);//图片大小
g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小
g.setColor(getRandColor(110, 133));//字体颜色
// 绘制干扰线
for (int i = 0; i <= lineSize; i++) {
drowLine(g);
}
// 绘制随机字符
String randomString = "";
for (int i = 1; i <= stringNum; i++) {
randomString = drowString(g, randomString, i);
}
logger.info(randomString);
//将生成的随机字符串保存到session中
session.removeAttribute(RANDOMCODEKEY);
session.setAttribute(RANDOMCODEKEY, randomString);
g.dispose();
try {
// 将内存中的图片通过流动形式输出到客户端
ImageIO.write(image, "JPEG", response.getOutputStream());
} catch (Exception e) {
logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);
}
}
/**
* 绘制字符串
*/
private String drowString(Graphics g, String randomString, int i) {
g.setFont(getFont());
g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
.nextInt(121)));
String rand = String.valueOf(getRandomString(random.nextInt(randString
.length())));
randomString += rand;
g.translate(random.nextInt(3), random.nextInt(3));
g.drawString(rand, 13 * i, 16);
return randomString;
}
/**
* 绘制干扰线
*/
private void drowLine(Graphics g) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
g.drawLine(x, y, x + xl, y + yl);
}
/**
* 获取随机的字符
*/
public String getRandomString(int num) {
return String.valueOf(randString.charAt(num));
}
}
使得验证码类生效
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PictureverifycodeApplication.class);
}
}
生成验证码、进行检验的工具类:
@RestController
@RequestMapping("/login") //用于获取验证码
public class Picverifyaction {
private final static Logger logger = LoggerFactory.getLogger(Picverifyaction.class);
/**
* 生成验证码
*/
@RequestMapping(value = "/getVerify")
public static void getVerify(HttpServletRequest request, HttpServletResponse response) {
try {
response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expire", 0);
RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
randomValidateCode.getRandcode(request, response);//输出验证码图片方法
} catch (Exception e) {
logger.error("获取验证码失败>>>> ", e);
}
}
/**
* 校验验证码
*/
@RequestMapping(value = "/checkVerify", method = RequestMethod.POST,headers = "Accept=application/json")
public static boolean checkVerify(@RequestParam String verifyInput, HttpSession session) {
try{
//从session中获取随机数
String inputStr = verifyInput;
String random = (String) session.getAttribute("RANDOMVALIDATECODEKEY");
if (random == null) {
return false;
}
if (random.equals(inputStr)) {
return true;
} else {
return false;
}
}catch (Exception e){
logger.error("验证码校验失败", e);
return false;
}
}
}
4、MVC模块的代码实现
1)JavaBean的编写
在springboot下使用hibernate,不需要进行配置,使用全注解的方式进行开发;
在实体类中需要对类进行注解@Entity、@Table(name = “数据库表名称”);
@Entity
@Table(name = "t_user") //指定数据库中对应的表格,若不指定则会在数据库中创建与实体类同名的表格,表格的每一列对应的成员变量
public class User {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "username")
private String username;
@Column(name = "pwd")
private String pwd;
//....
}
2)service和dao层的代码实现
****数据持久层中,只需要写接口类,并提供需要的方法即可,不需要写实现类;
接口类需要实现JPARepostity<T1,T2>同时制定实体类名称和其对应的表格的主键的包装类。
@Repository
public interface IUserDao extends JpaRepository<User,Integer> {
List<User> findUserByUsernameAndPwd(String username,String pwd);
}
*****在业务逻辑层,实现相应的业务处理:
@Service
public class UserService {
@Autowired
private IUserDao userDao;
public boolean verifyLoginUser(String username,String pwd){
List<User> list = userDao.findUserByUsernameAndPwd(username,pwd);
return list.size() > 0;
}
}
3)controller层获取数据并检验
在controller层中获取用户输入的信息,然后进行检验;检验成功后,转发success.html页面,并显示登陆成功的信息;
实现页面之间的转发以下提供两种方式:
first method:返回类型为String,即直接返回需要转发到的页面的名称即可;使用themleaf来实现,需要在properties文件中,配置
静态资源的转发路径:类路径下,templates文件下的文件
second method:使用spring mvc中ModelAndView类作为返回类型,直接返回一个ModelAndView的对象(可根据构造函数来进行选择实现的方式,可以直接传递一个字符串参数,即想要转发到的页面名称;或者创建一个ModelAndView对象,设置其属性名称,然后返回该对象。)
@Controller
public class LoginUserController {
@Autowired
private UserService userService;
@RequestMapping("/loginVerify")
public ModelAndView loginVerify(HttpServletRequest request, HttpSession session, Model model){
String username = request.getParameter("user-name-label");
String pwd = request.getParameter("password-label");
String inputStr = request.getParameter("verify_input");
System.out.println(username+pwd);
User user = new User(username,pwd);
model.addAttribute("user",user);
boolean verify = userService.verifyLoginUser(user.getUsername(),user.getPwd());
boolean verifyCode = Picverifyaction.checkVerify(inputStr,session);
if(verify && verifyCode){
return new ModelAndView("success.html");
// return "success";
}else{
return new ModelAndView("fail.html");
// return "fail";
}
}
@GetMapping("/test")
public String test(){
return "success";
}
}
在success.html中,使用themeleaf来显示用户的信息
<body>
<h1>springboot中,成功实现页面之间的转发,用于测试</h1>
<h1 th:text = ${user.username}></h1>登陆成功
</body>
5、实现检验