【Spring MVC】Spring MVC,阻止直接访问jsp,使用Interceptor登录拦截

本贴最后更新于 2882 天前,其中的信息可能已经水流花落

问题描述:

在Java Web项目中,用户可访问Url一般只有一个,即index或login。而用户的其他Url请求都会引导到index页。如何来避免未登录用户直接访问Spring的Conroller和jsp文件?

解决方案:

一、阻止用户访问jsp。

Spring的MVC模式是不提倡直接通过URL形式访问.jsp页面的,建议通过Controller跳转至View页面。

把jsp文件放在WEB-INF目录下,js和css等资源文件放在WEB-INF的同级目录下,WEB-INF对用户不可见,可以起到隔离作用。

同时修改mvc配置文件,配置jsp的路径。

1     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
2         <property name="prefix" value="/WEB-INF/jsp/" />
3         <property name="suffix" value=".jsp" />
4     </bean>

配置资源文件夹的路径,以便jsp能访问到所引用的静态资源文件。

<mvc:resources mapping="/**" location="/resources" />

二、Interceptor登录拦截

Spring拦截器介绍:

SpringMVC中使用Interceptor拦截器

拦截器HandlerInterceptor接口有三个回调方法

1.preHandle方法,顾名思义,该方法将在请求处理之前进行调用。SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。

2.postHandle方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。

3.afterCompletion方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。

 1 package org.springframework.web.servlet;  
 2 public interface HandlerInterceptor {  
 3     boolean preHandle(  
 4             HttpServletRequest request, HttpServletResponse response,   
 5             Object handler)   
 6             throws Exception;  
 7   
 8     void postHandle(  
 9             HttpServletRequest request, HttpServletResponse response,   
10             Object handler, ModelAndView modelAndView)   
11             throws Exception;  
12   
13     void afterCompletion(  
14             HttpServletRequest request, HttpServletResponse response,   
15             Object handler, Exception ex)  
16             throws Exception;  
17 } 

 

写自己的拦截器:

 1 public class LoginInterceptor extends HandlerInterceptorAdapter {
 2     private List<String> excludedUrls;
 3     public void setExcludeUrls(List<String> excludeUrls) {
 4         this.excludedUrls = excludeUrls;
 5     }
 6     @Override
 7     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 8         String requestUri = request.getRequestURI();
 9         for (String url : excludedUrls) {
10             if (requestUri.endsWith(url)) {
11                 return true;
12             }
13         }
14         HttpSession session = request.getSession();
15         if (session.getAttribute("login")==null) {
16             throw new WebAuthException();
17         } else {
18             return true;
19         }
20     }
21 }

HandlerInterceptorAdapter是适配器模式的接口,这里允许我们只实现一个方法即可。excludedUrls中声明了不需要拦截的URL,如果访问的URL以指定字符串结尾,preHandle将返回true,他们将不被拦截而直接访问到对应的Controller。声明方式可以在Spring配置文件中,如下

 1     <mvc:interceptors>
 2         <mvc:interceptor>
 3             <mvc:mapping path="/*"/>
 4             <bean id="loginInterceptor" class="LoginInterceptor">
 5                 <property name="excludeUrls">
 6                     <list>
 7                         <value>/index</value>
 8                        
 9                         <value>/</value>
10                     </list>
11                 </property>
12             </bean>
13         </mvc:interceptor>
14     </mvc:interceptors>

也就是说“http://xxxxxxxxxx/index”,“http://xxxxxxxxxx/login”,“http://xxxxxxxxxx/”是不会被拦截的。

如果URL不以指定字符串结尾,那么将判断session中是否已经有登录信息(用户是否已经登录),如果登录了,正常跳转到Controller。如果没有登录则抛出异常。该异常是自定义的:

1 public class WebAuthException extends Exception {
2 }

然后再配置文件中指定,抛出异常时,重定向到登录页。

1     <bean id="handlerExceptionResolver"
2           class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
3         <property name="exceptionMappings">
4             <props>
5                 <prop key="com.thisone.apiserver.exception.WebAuthException">redirect:/index</prop>
6             </props>
7         </property>
8     </bean>

注意,如果没有redirect:,则直接跳转至名为index.jsp的页面。有redirect则会由Controller中@RequestMapping(value="/login")的方法来处理它。

1 @Controller
2 public class SystemController {
3     @RequestMapping(value = {"/index","/"},
4             method = RequestMethod.GET)
5     public String home() {
6         return "login";  //返回到login.jsp登录页,而不是Controller的方法。
7     }
8 }
 1     @RequestMapping(value = "/login",
 2             method = RequestMethod.POST)
 3     public String login(HttpServletRequest request,
 4                         @RequestParam String loginname,
 5                         @RequestParam String password) throws Exception {
 6         if (!loginname.equals("xxxx")) {
 7             request.getSession().setAttribute("loginReply", "用户名错误, 请重新登录");
 8             return "login";
 9         }
10         if (!password.equals("xxxx")) {
11             request.getSession().setAttribute("loginReply", "密码错误, 请重新登录");
12             return "login";
13         }
14         request.getSession().setAttribute("login", "yes");
15         return "welcome";
16     }

 

这样,用户只能通过/index,/,三个URL后缀来正常访问到页面,其他都是会重定向到/index,再有Cntroller方法引导至login.jsp。

 

转:http://blog.csdn.net/a568078283/article/details/51333615

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 138 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 414 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    276 引用 • 686 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1384 回帖 • 363 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 466 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 156 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 618 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 570 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 45 关注
  • 音乐

    你听到信仰的声音了么?

    59 引用 • 509 回帖
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 93 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    89 引用 • 113 回帖
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 180 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 319 关注
  • 分享

    有什么新发现就分享给大家吧!

    242 引用 • 1746 回帖
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    22 引用 • 31 回帖 • 2 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    106 引用 • 152 回帖 • 2 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 608 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 113 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 22 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    15 引用 • 7 回帖 • 3 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 4 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 30 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖 • 1 关注