SpringMVC-02

SpringMVC

1.拦截器
   SpringMVC中的拦截器可以应用于许多请求,当用户尝试对指定的请求路径进行访问时,拦截器将被执行,且最终会根据具体情况进行拦截或放行。

2.创建一个拦截器

首先,自定义类,并实现【HandlerInterceptor】接口

public class LoginInterceptor implements HandlerInterceptor {

	public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("LoginInterceptor.preHandle()");
		return false;
	}
	
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
		System.out.println("LoginInterceptor.postHandle()");
	}
	
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
		System.out.println("LoginInterceptor.afterCompletion()");
	}
	
}

JDK1.8以后,允许接口中的方法包括方法体,需要在方法前添加【default】,spring框架自【5.0】版本后,就采用了这种写法,【5.1.6】版本【org.springframework.web.servlet】中的【HandlerInterceptor】接口,部分方法写法如下:

default boolean preHandle(
    HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
	return true;
}

default void postHandle(
    HttpServletRequest request, HttpServletResponse response, Object handler,
		@Nullable ModelAndView modelAndView) throws Exception {
}

default void afterCompletion(
    HttpServletRequest request, HttpServletResponse response, Object handler,
		@Nullable Exception ex) throws Exception {
}

接下来,需要在Spring的配置文件中对拦截器进行配置

<!-- 拦截器链 -->
<mvc:interceptors>
	<!-- 第1个拦截器 -->
	<mvc:interceptor>
		<!-- 拦截路径 -->
		<mvc:mapping path="/main/index.do"/>
		<!-- 拦截器类 -->
		<bean class="cn.tedu.spring.LoginInterceptor" />
	</mvc:interceptor>
</mvc:interceptors>

完成后,即可开始测试,成功拦截效果是【页面显示一片空白】,并且,在拦截器的3个方法中,只有【preHandle()】被执行。在拦截器的【preHandle()】方法运行时,返回【false】表示【拦截】,返回【true】表示【放行】,并且,【postHandle()】和【afterCompletion()】方法都是在【preHandle()】之后的,且仅当【放行】时执行。

关于拦截器的配置,可以配置多项拦截路径,也可以添加【例外】即【白名单】:

<!-- 拦截器链 -->
<mvc:interceptors>
	<!-- 第1个拦截器 -->
	<mvc:interceptor>
		<!-- 1. 拦截路径(黑名单) -->
		<mvc:mapping path="/main/*"/>
		<mvc:mapping path="/news/*"/>
		<mvc:mapping path="/user/*"/>
		<!-- 2. 例外(白名单) -->
		<mvc:exclude-mapping path="/user/reg.do"/>
		<mvc:exclude-mapping path="/user/handle_reg.do"/>
		<mvc:exclude-mapping path="/user/login.do"/>
		<mvc:exclude-mapping path="/user/handle_login.do"/>
		<!-- 3. 拦截器类 -->
		<bean class="cn.tedu.spring.LoginInterceptor" />
	</mvc:interceptor>
</mvc:interceptors>

凡是不在黑名单中的访问路径,或在白名单的访问路径,都不会触发拦截器的执行。在配置拦截器的拦截路径或例外路径时,可以使用通配符:【*】表示某层路径或某个资源,例如【/user/*】可以通配 “/user/reg.do” 及 “/user/login.do” 等,【?】可以通配1个字符,【**】可以通配多层级内容,例如 ”/user/**“ 可以通配 “/user/1/edit” 及 ”/user/1/delete“ 等。

拦截器与过滤器

       拦截器与过滤器有高度相似之处,例如都可以应用于许多请求,并且都可以起到“拦截”的效果,也都可以存在多个过滤器或多个拦截器形成“链”。
关于这两者的区别:
1.归属不同,过滤器是Java EE中的组件,而拦截器是SpringMVC中的组件,所以,只要开发Java WEB项目,都可以使用过滤器,但是,仅当开发Java WEB项目且使用了SpringMVC框架才可以使用拦截器,并且,由于拦截器是SpringMVC框架下的,只有被DispatcherServlet处理的请求才有可能被拦截器处理,该请求后缀为【.do】;
2.配置不同,过滤器的配置在web.xml中配置的,能配置的节点比较单一,但拦截器的配置非常灵活,可以通过【mvc:mapping】节点配置黑名单,也可以通过【mvc:exclude-mapping】节点配置白名单;
3.执行时间节点不同,过滤器是执行在所有Servlet之前的,而拦截器的第1次执行是执行在DispatcherServlet之后且在Controller之前的,但由于时间节点不同,拦截器也不能取代过滤器,如设置编码格式等。

解决乱码问题

       计算机能够直接识别并处理的都是二进制数据,也就是由【0】和【1】组成的序列,每个存储0或1的空间称为【位】,位数越多,可以表达的状态就越多,如【byte】有8位,可以表示256种状态。在ASCII编码表中,指定了人类生活使用的字符与二进制的对应关系,如【‘a’】对应数字【97】等。
      由于ASCII编码表只指定了一个字节的对应关系,但是中文汉字数量太多,一个字节无法表达,两个字节有16位,可以表达3W以上的字符了,Java语言在处理字符是,内存中就使用了Unicode编码,当进行数据传输时,如果传输的是【a】,只需要一个字节就够了,如果传输汉字【海】,则必须使用两个字节,如果单纯的直接传输二进制数字的序列,对方便不知道如何分割,为了保证能够正确分割这些二进制的序列,就产生了传输编码,如【utf8】,其格式为:

几个字节几个1 后续均为10开头
两个字节:  110x xxxx 10xx xxxx
三个字节:  1110 xxxx 10xx xxxx 10xx xxxx  常用版本   utf8mb3  ---- max bytes 3
四个字节:  1111 0xxx 10xx xxxx 10xx xxxx  不常用版本 utf8mb4  ---- max bytes 4

        当然,目前还有很多其他格式的编码,如【GBK】【GB2312】【ISO8859-1】【latin1】等,不同的编码格式都不相同,甚至有些编码格式不支持中文,当发送和接受两方使用的编码格式不相同时,处理数据的时候就会出现编码无法解析的情况,显示结果即为乱码。所以乱码问题都是因为使用编码不统一造成的,所以解决方案就是统一使用编码格式,常见需要指定编码格式的文件有:项目源码、网络传输和接收的编码格式、网页界面、数据库连接等。为避免出现乱码情况,通常需要指定编码格式的位置,通通使用utf8编码。

通过过滤器设置编码格式

       由于拦截器实在Dispatcher之后,Controller之前执行的,在此期间,请求的编码格式已经确定,而前端处理器类并非我们自己编写,无法设置编码格式,因此,可以通过早于拦截器执行的过滤器来设置请求编码格式。如下:
       在配置文件【web.xml】中添加过滤器配置

 <filter>
  	<filter-name>CharacterEncodingFilter</filter-name>
    //SpringMVC框架中写好了一个编码过滤器类,我们可以直接使用
  	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  	<init-param>
    //通过观察该类源码,可以发现,通过设置初始化参数encoding可以设置指定编码格式
  		<param-name>encoding</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
//源码片段	
@Override
	protected void doFilterInternal(
		HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		String encoding = getEncoding();
		if (encoding != null) {
			if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
				request.setCharacterEncoding(encoding);
			}
			if (isForceResponseEncoding()) {
				response.setCharacterEncoding(encoding);
			}
		}
		filterChain.doFilter(request, response);
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值