一、需求分析
本项目主要是对用户登录状态的验证,只有登录成功的用户才可以访问系统中的资源。为了保证后台系统的页面不能被客户直接请求访问,本案例中所有的页面都存放在项目的WEB-INF 文件夹下,客户需要访问相关页面时,需要在服务器端转发到相关页面。如果没有登录系统而直接访问系统首页,拦截器会将请求拦截,并转发到登录页面,同时在登录页面中给出提示信息。如果用户登录时提交的用户名或密码错误,也会在登录页面给出相应的提示信息。当已登录的用户在系统页面中单击“退出”链接时,系统同样会回到登录页面。
二、实现需求
本项目未涉及到与数据库的交互,只分析web层操作,对登录所需的验证部分用固定值进行验证操作
Controller层完成业务需求
页面跳转
登录功能
退出功能
Interceptor拦截器完成
拦截器校验登录状态
后台系统登录验证流程图
三、参考代码
创建一个Spring MVC工程,导入相关依赖
pom.xml可复用代码
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>SpringMVCdemo01</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 声明当前是一个maven的web工程-->
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- Spring的核心基本包 ioc相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.26</version>
</dependency>
<!-- 服务器相关配置-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!--依赖范围-->
<scope>provided</scope>
</dependency>
<!-- jdbc相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.26</version>
</dependency>
<!-- spring事务相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.26</version>
</dependency>
<!-- springAOP相关-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- Spring MVC相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version> <!-- 版本号根据您的实际情况进行调整 -->
</dependency>
<!-- jackson依赖,用于JSON数据绑定,因为它各个方面表现均非常优秀,是世界最流行、最好的JSON库-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.5</version>
</dependency>
</dependencies>
<build>
<!-- 加入tomcat插件-->
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 解决get请求乱码问题-->
<uriEncoding>utf-8</uriEncoding>
<port>8080</port> <!-- 访问端口-->
<!--虚拟项目名-->
<path>/SpringMVCdemo01</path> <!-- 访问路径,一般就是你的项目名注意前面有个‘/’-->
</configuration>
</plugin>
</plugins>
</build>
</project>
1、编写绑定数据的pojo的user类
创建User类,在User类中,声明username和password属性,分别表示用户名和密码,并定义了每个属性的getter/setter方法
package com.yx.pojo;
//POJO用于数据绑定
public class User {
// 实体的属性名应该和页面提交的参数一致
private String username;//用户名
private String password;//用户密码
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
2、在cotroller层实现定义跳转到系统首页、跳转到登录页面、跳转到订单信息页面、用户登录和用户退出五个方法
package com.yx.controller;
import com.yx.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
@Controller
public class UserController {
// 页面跳转
@RequestMapping("/main")
public String main(){
return "main";//采用视图解析器进行操作
}
// 页面跳转
@RequestMapping("/toLogin")
public String toLogin(){
return "login";//采用视图解析器进行操作
}
// 页面跳转
@RequestMapping("/orderinfo")
public String orderinfo(){
return "orderinfo";//采用视图解析器进行操作
}
// 登入
@RequestMapping("/login")
public String login(User user, Model model,HttpSession session){
//判断用户名和密码
String username = user.getUsername();
String password=user.getPassword();
if (username !=null&&"zhangsan".equals(username)&&password!=null&&"123456".equals(password)){
//登入成功,跳转到首页并且保存用户信息
// 一定要保存信息要不然会无法跳转到查看页
session.setAttribute("user",user);
return "main";
}else {
//登入失败,给出失败信息,跳转到登入界面
model.addAttribute("msg","用户名或密码错误");
return "login";
}
}
// 退出成功需要跳转到登录页面
@RequestMapping("/logout")
public String logout(HttpSession session){
//清空session,销毁当前登入的用户的信息
session.invalidate();
return "login";
}
}
3、创建拦截器LoginInterceptor,在重写的preHandle()方法中对请求进行拦截。LoginInterceptor类中部分代码
package com.yx.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//拦截器校验登入状态
public class Logininterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 针对登入和跳转到登入页面的请求进行放行
String requestURI=request.getRequestURI();
if(requestURI.indexOf("/login")>0||requestURI.indexOf("/toLogin")>0){
//直接放行
return true;
}
// 其他请求需要做登录权限拦截判断
HttpSession session=request.getSession();
if (session.getAttribute("user")!=null) { return true; }
// 其他情况都直接跳转到登录页面
request.setAttribute("msg", "您还没有登录,请先登录!");
//此处视图解析器不生效,使用的时Javaweb原生技术
request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request,response);
return false;
}
//以下暂时不做操作
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
4、在Spring MVC配置文件spring-mvc.xml中配置包扫描、注解驱动、视图解析器、拦截器和静态资源访问映射
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tool="http://www.springframework.org/schema/mvc" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 注解扫描-->
<context:component-scan base-package="com.yx.controller"/>
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
<!-- 前缀-->
<property name="prefix" value="/WEB-INF/pages/"/>
</bean>
<!-- 装载转换器:支持JSON的-->
<tool:annotation-driven></tool:annotation-driven>
<!--释放静态资源,配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 如:jq的访问-->
<!-- <mvc:resources mapping="/js/**" location="/js/" />-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<mvc:interceptors>
<!-- 配置局部单个的拦截器-->
<!-- <mvc:interceptor>-->
<!--<!– 这里只针对demo1方法执行时进行了拦截操作–>-->
<!-- <tool:mapping path="/demo1"/>-->
<!-- <bean class="com.yx.interceptor.CustomInterceptor"></bean>-->
<!-- </mvc:interceptor>-->
<!-- 配置 MyIntrceptor拦截器 -->
<!-- <bean class="com.yx.interceptor.MyIntrceptor"></bean>-->
<!-- 配置 Logininterceptor拦截器 -->
<bean class="com.yx.interceptor.Logininterceptor"></bean>
</mvc:interceptors>
</beans>
5、在pages文件夹中创建名称为main.jsp文件作为系统首页。在main.jsp中展示当前登录的用户名、用户退出页面的超链接和订单信息页面的超链接
注意:jsp代码的位置在webapp/WEB-INF/pages里面
Main.jsp
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/3/10
Time: 17:00
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html><head><title>后台系统</title></head>
<body>
<li>您好:${ user.username }</li>
<li> <a href="${ pageContext.request.contextPath }/logout">退出</a></li>
<li><a href="${ pageContext.request.contextPath }/orderinfo">订单信息</a></li>
</body></html>
Login.jsp
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/3/10
Time: 16:35
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户登入</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login"
method="post">
<div>${msg}</div>
用户名:<input type="text" name="username" /><br />
密 码:<input type="password" name="password" /><br />
<input type="submit" value="登录"/>
</form>
</body>
</html>
orderinfo.jsp
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2024/3/10
Time: 17:01
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><title>订单信息</title></head><body>
您好:${ user.username }
<a href="${ pageContext.request.contextPath }/logout">退出</a>
<table border="1" width="80%">
<tr align="center"><td colspan="2" >${ user.username }订单id:D001</td></tr>
<tr align="center"><td>商品Id</td><td>商品名称</td></tr>
<tr align="center"><td>P001</td><td>九江鱼块</td></tr>
<tr align="center"><td>P002</td><td>南昌拌粉</td></tr>
</table>
</body></html>
6、 效果
未登录时:
输入用户名:zhangsan,密码:12345(错误密码)提示用户名或密码有误
输入用户名:zhangsan,密码:123456(正确密码)
点击订单信息
点击退出(回到登录页)