登录功能算是系统的必要的功能,在此文中将完成该功能的后台。最终项目结构如下
1.配置相关文件依赖
新建SpringBoot项目login_demo,
首先在POM文件中添加web、mybatis、jdbc、mysql、验证码依赖。
1.web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.mybatis
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
3.jdbc和mysql
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
4.验证码,这里用的是google的kaptcha
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
配置property,打开文件application.properties文件,添加如下配置
这里的配置mysql的就是定义数据库的连接方式、配置8小时失效问题、连接池。mybatis的就是映射文件所在目录
#mysql config
spring.datasource.name=springdemo-datasource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springdemo_db?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=hikariCP
spring.datasource.hikari.max-lifetime=30000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
# mybatis config
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
2.Dao层
1.新建entity包,存放对象,该包下新建java类User,并为其添加getter和setter和toString方法。
public class Userimplements Serializable {
private int id;
private Stringusername;
private Stringpassword;
2.新建包dao,该包下新建Java接口UserDao.
新建方法login(),该方法用户登录的数据库映射方法,参数为username和password.
public interface UserDao {
User login(@Param("username") String username,@Param("password") String password);
}
3.打开项目启动类,添加MapperScanner注解,让其映射到新建的dao
@SpringBootApplication
@MapperScan("lan.springbootdemo.login.login_demo.dao")
public class LoginDemoApplication {
public static void main(String[] args) {
SpringApplication.run(LoginDemoApplication.class, args);
}
}
4.resources资源管理文件下新建文件夹mapper,mapper文件夹下新建xml文件,文件名为UserMapper。编辑该文件,书写mybatis。
<?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="lan.springbootdemo.login.login_demo.dao.UserDao">
<resultMap id="userResult" type="lan.springbootdemo.login.login_demo.entity.User">
<id property="id" column="id" jdbcType="INT"></id>
<result property="username" column="username" jdbcType="VARCHAR"></result>
<result property="password" column="password" jdbcType="VARCHAR"></result>
</resultMap>
<select id="login" resultMap="userResult">
select id,username,password
from user
where username=#{username} and password=#{password}
</select>
</mapper>
3.Service层
1.新建service包,包下新建java接口文件UserService,该接口提供用户登录方法。
public interface UserService {
User login(String username,String password);
}
2.service包下新建impl包,impl包下新建UserService的实现类UserServiceImpl.java,为该类添加Service注解。
@Service
public class UserServiceImplimplements UserService {
@Resource
UserDao userDao;
@Override
public User login(String username, String password) {
return userDao.login(username,password);
}
}
4.验证码功能
1.根目录新建config包,该包下新建KaptchaConfig.java,该类要将Kaptcha的验证码对象DefaultKaptcha注入IOC容器。
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha(){
com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha =new com.google.code.kaptcha.impl.DefaultKaptcha();
Properties properties =new Properties();
properties.put("kaptcha.border","no");
properties.put("kaptcha.textproducer.font.color","black");
properties.put("kaptcha.image.width","150");
properties.put("kaptcha.image.height","40");
properties.put("kaptcha.textproducer.font.size","30");
properties.put("kaptcha.session.key","verifyCode");
properties.put("kaptcha.textproducer.char.space","5");
Config config =new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
2.验证码网络请求处理器
根目录新建common包,该包下新建CommonController.java,因为验证码功能整个项目很多地方都能用到,因此将该功能拿出来作为公共功能。
@Controller
public class CommonController {
@Autowired
private DefaultKaptchacaptchaProducer;
@GetMapping("/kaptcha")
public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)throws Exception {
byte[] captchaOutputStream =null;
ByteArrayOutputStream imgOutputStream =new ByteArrayOutputStream();
try {
//验证码保存到session
String verifyCode =captchaProducer.createText();
httpServletRequest.getSession().setAttribute("verifyCode", verifyCode);
BufferedImage challenge =captchaProducer.createImage(verifyCode);
ImageIO.write(challenge,"jpg", imgOutputStream);
}catch (IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
captchaOutputStream = imgOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control","no-store");
httpServletResponse.setHeader("Pragma","no-cache");
httpServletResponse.setDateHeader("Expires",0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
responseOutputStream.write(captchaOutputStream);
responseOutputStream.flush();
responseOutputStream.close();
}
}
5.处理登录请求
根目录新建controller包,该包下新建UserController.java,处理登录请求。
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
UserServiceuserService;
@PostMapping("/login")
public void login(@RequestParam("username") String username,@RequestParam("password") String password,
@RequestParam("verifyCode") String verifyCode,
HttpSession session) {
if (StringUtils.isEmpty(verifyCode)) {
session.setAttribute("errorMsg","验证码不能为空");
}
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
session.setAttribute("errorMsg","用户名或密码不能为空");
}
String kaptchaCode = session.getAttribute("verifyCode") +"";
if (StringUtils.isEmpty(kaptchaCode) || !verifyCode.equals(kaptchaCode)) {
session.setAttribute("errorMsg","验证码错误");
}
User user =userService.login(username,password);
if(user!=null){
session.setAttribute("loginUserName", user.getUsername());
session.setAttribute("loginUserId", user.getId());
//成功 执行跳转
//..........
}else{
session.setAttribute("errorMsg","登录信息错误");
}
}
}
6.登录拦截器
如果用户处于未登录状态就访问,那么我们肯定要拦截回来,SpringBoot为我们提供了一个拦截器,我们只要实现其就好,根目录新建interceptor包,包下新建LoginInterCeptor.java类,注解Component,实现PreHandler方法,PreHandler就是在其他处理器接收之前先处理一下。
@Component
public class LoginInterCeptorimplements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
String uri = request.getRequestURI();
if(uri.startsWith("/user") && (request.getSession().getAttribute("loginUserName")==null)){
request.getSession().setAttribute("errorMsg","请登录");
//
response.sendRedirect(request.getContextPath()+"/user/login");
return false;
}
request.getSession().removeAttribute("errorMsg");
return true;
}
}
7.结束
到这,登录就完成了。工程目录如下