博客
关于我
手写Spring MVC框架(二) 实现访问拦截功能
阅读量:746 次
发布时间:2019-03-22

本文共 9574 字,大约阅读时间需要 31 分钟。

Spring MVC实现访问拦截功能

前言

在上一篇文章中,我们手写了一个简单的MVC框架,今天我们要在Spring MVC框架基础上实现访问拦截功能。这个功能的实现主要包含以下几点:定义一个@Security注解,用于标注需要权限的控制器方法;通过拦截器来验证用户权限;以及在URL中直接传递用户名进行权限验证。

实现过程

1、项目依赖

项目依赖文件在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>com.hardy.edu</groupid>
<artifactid>springmvc-demo</artifactid>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>springmvc-demo Maven Webapp</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceencoding>UTF-8</project.build.sourceencoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!--引入Spring Web MVC依赖-->
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-webmvc</artifactid>
<version>5.1.12.RELEASE</version>
</dependency>
<!--引入Javax Servlet API-->
<dependency>
<groupid>javax.servlet</groupid>
<artifactid>javax.servlet-api</artifactid>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--引入JSON处理依赖-->
<dependency>
<groupid>org.json</groupid>
<artifactid>json</artifactid>
<version>20140107</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.apache.tomcat.maven</groupid>
<artifactid>tomcat7-maven-plugin</artifactid>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>

2、注解开发

定义Security注解:

package com.hardy.edu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Security {
String[] value() default {};
}

3、拦截器开发

实现SecurityInterceptor拦截器:

package com.hardy.edu.interceptor;
import com.hardy.edu.annotation.Security;
import org.json.JSONObject;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class SecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("SecurityInterceptor preHandle......");
String username = request.getParameter("username");
HandlerMethod method = (HandlerMethod) handler;
Security annotation = method.getMethod().getAnnotation(Security.class);
String[] value = annotation.value();
boolean isHavePermissionName = false;
if (value != null) {
for (int i = 0; i < value.length; i++) {
if (username.equals(value[i])) {
isHavePermissionName = true;
break;
}
}
}
if (!isHavePermissionName) {
JSONObject jsonObject = new JSONObject();
jsonObject.append("error", "没有访问权限");
System.out.println("该用户没有访问权限!");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(jsonObject.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("SecurityInterceptor postHandle......");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("SecurityInterceptor afterCompletion......");
}
}

4、类型转换器开发

自定义日期转换器:

package com.hardy.edu.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter
{
@Override
public Date convert(String source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date parse = simpleDateFormat.parse(source);
return parse;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}

5、控制器开发

实现DemoController:

package com.hardy.edu.controller;
import com.hardy.edu.annotation.Security;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
@RequestMapping("/demo")
public class DemoController {
@Security(value = {"hardy", "zhangsan", "lisi"})
@RequestMapping("/testSecurity")
public ModelAndView testSecurity(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
String username = request.getParameter("username");
ModelAndView modelAndView = new ModelAndView();
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
modelAndView.addObject("date", simpleDateFormat.format(date));
modelAndView.addObject("username", username);
modelAndView.setViewName("success");
return modelAndView;
}
}

6、配置文件

Web.xml配置:

<?xml version="1.0" encoding="UTF-8"?
<web-app>
<!-- springmvc 提供的针对post请求的编码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 配置springmvc请求方式转换过滤器-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<!-- 注册拦截器-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>

7、JSP页面

错误页面error.jsp:

<%@ page language="java" isELIgnored="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<!-- 异常信息显示 -->
<${msg}>

成功页面success.jsp:

<%@ page language="java" isELIgnored="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<!-- 显示用户名和服务器时间 -->
<${username}:跳转成功!服务器时间:${date}>

项目整体结构

项目运行结果

启动项目后,访问以下地址可以看到不同的结果:

http://localhost:8080/demo/testSecurity?username=hardy

由于hardy在授权列表中,可以正常访问。

http://localhost:8080/demo/testSecurity?username=wangwu

由于wangwu不在授权列表中,无法访问。

总结

今天我们在Spring MVC框架基础上实现了简单的访问拦截功能。通过@Security注解和SecurityInterceptor拦截器,我们可以根据请求中的username参数验证用户权限。如果用户没有权限,系统会返回JSON格式的错误信息;如果有权限,用户可以正常访问资源。这个实现虽然简单,但可以作为基础,进一步扩展成一个完整的用户登录拦截系统。

转载地址:http://uikwk.baihongyu.com/

你可能感兴趣的文章
MySQL Connector/Net 句柄泄露
查看>>
multiprocessor(中)
查看>>
mysql CPU使用率过高的一次处理经历
查看>>
Multisim中555定时器使用技巧
查看>>
MySQL CRUD 数据表基础操作实战
查看>>
multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
查看>>
mysql csv import meets charset
查看>>
multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
查看>>
MySQL DBA 数据库优化策略
查看>>
multi_index_container
查看>>
MySQL DBA 进阶知识详解
查看>>
Mura CMS processAsyncObject SQL注入漏洞复现(CVE-2024-32640)
查看>>
Mysql DBA 高级运维学习之路-DQL语句之select知识讲解
查看>>
mysql deadlock found when trying to get lock暴力解决
查看>>
MuseTalk如何生成高质量视频(使用技巧)
查看>>
mutiplemap 总结
查看>>
MySQL DELETE 表别名问题
查看>>
MySQL Error Handling in Stored Procedures---转载
查看>>
MVC 区域功能
查看>>
MySQL FEDERATED 提示
查看>>