Initialize project
1. Create a new Spring Boot project, add web by default, and wait for the completion of the construction. After the completion, the directory structure is as follows:
. ├── HELP.md ├── login-session-demo.iml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ ├── resources │ │ └── webapp │ └── test │ └── java └── target
pom file
Where, POM The XML content is as follows
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.terwergreen</groupId> <artifactId>login-session-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>login-session-demo</name> <description>login-session-demo</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Create login controller
2. Create LoginController, add @ Controller annotation, and add corresponding methods
/** * Login controller * * @name: LoginController * @author: terwer * @date: 2022-01-24 16:36 **/ @RequestMapping("/login") @Controller public class LoginController { @RequestMapping(value = "/toLogin", method = RequestMethod.GET) public String toLogin() { return "login"; } @RequestMapping(value = "login", method = RequestMethod.POST) public String login(String username, String password) { if ("test".equals(username) && "test".equals(password)) { return "redirect:/result.jsp"; } return "login"; } }
Configure template path mapping
3. Configure application Properties, set the port, and the jsp template prefix and suffix of spring MVC
server.port=8081 spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
Then add the webapp/WEB-INF/jsp directory under main
Create a new login JSP file.
4. A problem occurs and access http://localhost:8081/login/toLogin Error 404 is reported and printed on the console
Reason: jsp is not supported by default. Need to be in POM XML add the following jar package to support jsp
<!--jsp Page usage jstl label --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <!--For compilation jsp --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency>
Reload POM XML, then restart the project and access it again http://localhost:8081/login/toLogin , the page appears correctly
Hot deployment
5. Add hot deployment
In order to modify the file and see the effect in time, you can add a hot deployment plug-in.
<!-- Hot deployment --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
Add interceptor to realize login verification
6. Add interceptor for login verification
Create login interceptor
/** * Login interceptor * * @name: LoginInterceptor * @author: terwer * @date: 2022-01-24 17:46 **/ @Component public class LoginInterceptor implements HandlerInterceptor { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Using Session to verify login status to realize login interception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info("Enter login interceptor"); HttpSession session = request.getSession(); Object username = session.getAttribute(Constant.SESSION_USERNAME_KEY); if (null == username) { logger.info("No login or login failure"); response.sendRedirect(request.getContextPath() + "/login/toLogin"); return false; } logger.info("from Session Login name obtained in:" + username); return true; } }
Register the login interceptor to Spring Boot
/** * Spring MVC Custom configuration * * @name: MyWebMvcConfigAdaptor * @author: terwer * @date: 2022-01-24 17:51 **/ @Configuration public class MyWebMvcConfigAdaptor implements WebMvcConfigurer { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // Register interceptor // Block all by default // Exclude the login page itself and the error page registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login/**", "/error"); logger.info("Login interceptor added"); } }
Integrated mybatis
7. Integrated mybatis
mybatis integration
pom.xml is added to mybatis dependency and mysql database
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.1</version> </dependency> <!--mysql Driving coordinates--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> <scope>runtime</scope> </dependency>
Configuration file configuration data source, mybatis
# mybatis mybatis.mapper-locations=classpath:com/terwergreen/dao/*.xml # mysql spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Create Mapper
/** * User mapping class * * @name: UserMapper * @author: terwer * @date: 2022-01-24 21:44 **/ public interface UserMapper{ public User findByCondition(User user); }
mapper mapping
<?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.terwergreen.dao.UserMapper"> <select id="findByCondition" parameterType="com.terwergreen.pojo.User" resultType="com.terwergreen.pojo.User"> select * from user where username=#{username} and password=#{password} </select> </mapper>
service business processing
/** * Login service * * @name: LoginServiceImpl * @author: terwer * @date: 2022-01-24 22:06 **/ @Service public class LoginServiceImpl implements LoginService { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SqlSession session; public boolean doLogin(String username, String password) { logger.info("Start processing login"); User user = new User(); user.setUsername(username); user.setPassword(password); // User result = session.selectOne("findByCondition", user); UserMapper userMapper = session.getMapper(UserMapper.class); User result = userMapper.findByCondition(user); if (null != result) { logger.info("User information verification succeeded"); return true; } logger.info("The user does not exist or the password is incorrect"); return false; } }
General implementation optimization and problems
controller login processing
@RequestMapping(value = "login", method = RequestMethod.POST) public String login(String username, String password, HttpServletRequest request) { HttpSession session = request.getSession(); if (loginService.doLogin(username, password)) { request.getSession().setAttribute(Constant.SESSION_USERNAME_KEY, username); session.setAttribute(Constant.SESSION_LOGIN_FAIL_MSG_KEY, ""); return "redirect:/demo/result"; } session.setAttribute(Constant.SESSION_LOGIN_FAIL_MSG_KEY, Constant.SESSION_LOGIN_FAIL_MSG); return "login"; }
Use interceptor to intercept login
Interceptor implementation
Create a new LoginInterceptor to implement the HandlerInterceptor interface and intercept it in the preHandle
/** * Login interceptor * * @name: LoginInterceptor * @author: terwer * @date: 2022-01-24 17:46 **/ @Component public class LoginInterceptor implements HandlerInterceptor { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Using Session to check login status to realize login interception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info("Enter login interceptor"); HttpSession session = request.getSession(); Object username = session.getAttribute(Constant.SESSION_USERNAME_KEY); if (null == username) { logger.info("No login or login failure"); // session.setAttribute( Constant.SESSION_LOGIN_FAIL_MSG_KEY, Constant.SESSION_LOGIN_FAIL_MSG); response.sendRedirect(request.getContextPath() + "/login/toLogin"); return false; } session.setAttribute( Constant.SESSION_LOGIN_FAIL_MSG_KEY, ""); logger.info("from Session Login name obtained in:" + username); return true; } }
Register interceptor
/** * Spring MVC Custom configuration * * @name: MyWebMvcConfigAdaptor * @author: terwer * @date: 2022-01-24 17:51 **/ @Configuration public class MyWebMvcConfigAdaptor implements WebMvcConfigurer { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // Register interceptor // Block all by default // Exclude the login page itself and the error page registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login/**", "/error"); logger.info("Login interceptor added"); } }
Save the session to redis to solve the problem
When the above implementation implements the Nginx polling policy, there will be inconsistent login sessions. The solution is to save the session to redis. The specific method is to add the corresponding starter to seamlessly integrate redis.
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
Deployment validation
nginx configuration
upstream loginServer{ # For the convenience of testing, 127.0.0.1 is used server 127.0.0.1:8080; server 127.0.0.1:8081; # server 192.168.136.134:8080; # server 192.168.136.134:8081; } server { # Listening port listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; # Default request location / { proxy_pass http://loginServer/; # root html; # index index.html index.htm; } }
Package with maven, and then put the war package into the webapps directory of tomcat.
Finally, access the test.
If it is a local deployment, it can be accessed
http://127.0.0.1:8081/logindemo/login/toLogin
Otherwise, replace 127.0.0.1 with server ip.
Refer to the video for details
https://www.bilibili.com/video/BV1xa411m7RC/
Complete code
https://github.com/terwer/login-session-demo