需求

前端请求的header里带有Prefer_Lang参数,向后端传递国际化信息,后端需要在处理业务之前(建立拦截机制),将Prefer_Lang保存于线程上下文。

思路分析

初次接收该需求时,为了不改变既有代码而捕获request中的Prefer_Lang参数,脑海中第一反应是拦截器的概念。

方案一

Servlet的javax.servlet.Filter 或起源于Spring Security的org.springframework.web.filter.DelegatingFilterProxy

要点分析

  • 这种Filter在web.xml中配置,表面上能满足需求,但Filter与web容器耦合,不利于将国际化模块提供给第三方使用

方案二

SpringMVC的org.springframework.web.servlet.HandlerInterceptor

具体实施

  • 在spring mvc的xml中配置,基于request-response模型进行拦截,与方案一Filter类似
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.shjv.tdscdma.omc.server.platform.web.interceptor.LanguageInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

要点分析

  • 仔细探讨需求后,发现我们仅需要对Controller的调用进行拦截即可,只有Controller的调用才与后端国际化逻辑有关
  • 该方案对包括html、js等等与后端国际化逻辑无关的任意请求皆进行拦截,无意义地消耗大量系统资源
  • 虽然request-response模型上的拦截机制不可取,但是拦截也是AOP概念中的一部分,故有更优方案

方案三

Spring古老的AOP技术org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

具体实施

  • 在spring mvc的xml中配置,为所有beanNameController为后缀的bean生成代理对象
<bean id="languageInterceptor"
class="com.shjv.tdscdma.omc.server.platform.web.interceptor.LanguageInterceptor"></bean>
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Controller</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>languageInterceptor</value>
</list>
</property>
</bean>

要点分析

  • 表面上,该方案很好地实现了对所有beanNameController为后缀的bean进行拦截,没有方案二浪费系统资源的弊端。
  • 但是,无法保证开发人员自行编写的其他bean就不会以Controller为后缀
  • 同时,无法保证开发人员编写的Controller类就一定是以ControllerbeanName后缀
  • 我们知道,编写的Controller能为Spring MVC调度,是因为从代码结构上,强制了Controller类必须标注@Controller的注解,故有更优方案

方案四

Spring AOP的XML配置

具体实施

  • 在spring mvc的xml中配置,拦截所有标注@Controller的注解的Controller
<bean id="languageInterceptor"
class="com.shjv.tdscdma.omc.server.platform.web.interceptor.LanguageInterceptor"></bean>
<aop:config>
<aop:aspect ref="languageInterceptor">
<aop:before method="trapLanguage"
pointcut="execution(* *(..)) and within(@org.springframework.stereotype.Controller *)"/>
</aop:aspect>
</aop:config>

要点分析

  • 目前看来,该方案已经近乎完美地满足了我们的需求,通过within(@org.springframework.stereotype.Controller *)只拦截Spring MVC中的Controller的public方法

    做到。
  • 如果你与我一样是个XML Hater,我们还有更优雅的实现方式。

方案五

Spring AOP的Annotation配置。

具体实施

  • 在此,我们更进一步,只拦截Controller下标注了@RequestMapping的公共方法,JAVA代码如下
@Component
@Aspect
public class LanguageInterceptor {
@Pointcut("execution(@org.springframework.web.bind.annotation.RequestMapping * *(..)) && within(@org.springframework.stereotype.Controller *)")
public void controllerMethod() {
} @Before("controllerMethod()")
public void trapLanguage() {
final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
LanguageOption.setPreferLang(request == null ? null : request.getHeader("Prefer_Lang"));
}
}
  • 在spring mvc的xml中配置如下
<aop:aspectj-autoproxy />

Spring拦截机制之后端国际化心得的更多相关文章

  1. 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存

    首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...

  2. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  3. 两个开源的 Spring Boot + Vue 前后端分离项目

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  4. spring拦截器中修改响应消息头

    问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...

  5. Spring 拦截器实现+后台原理(HandlerInterceptor)

    过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...

  6. Hibernate工作原理及为什么要用?. Struts工作机制?为什么要使用Struts? spring工作机制及为什么要用?

    三大框架是用来开发web应用程序中使用的.Struts:基于MVC的充当了其中的试图层和控制器Hibernate:做持久化的,对JDBC轻量级的封装,使得我们能过面向对象的操作数据库Spring: 采 ...

  7. Spring Filter过滤器,Spring拦截未登录用户权限限制

    转载自:http://pouyang.iteye.com/blog/695429 实现的功能:判断用户是否已登录,未登录用户禁止访问任何页面或action,自动跳转到登录页面.  比较好的做法是不管什 ...

  8. spring工作机制及为什么要用?

    spring工作机制及为什么要用?1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作.2.DispatcherSer ...

  9. Spring(五)Spring缓存机制与Redis的结合

    一.Redis和数据库的结合 使用Redis可以优化性能,但是存在Redis的数据和数据库同步的问题. 例如,T1时刻以将 key1 保存数据到 Redis,T2时刻刷新进入数据库,但是T3时刻发生了 ...

随机推荐

  1. MyBatis的一系列问题的处理(遍历Map集合和智能标签和属性和字段不一样的解决办法 和sql片段)(三)

    一.字段名与属性名(数据库的名字)不一样怎么办? 方案一:在小配置中配置一个resultMapper <!--方案一:resultMapper 字段名与属性名不一致 --> <res ...

  2. SharePoint2016母版页的直接依赖项的数目限制超过10的限制解决方案Direct Dependencies Limit with Master page User Controls

    前言 最近母版制作站点模板,根据站点模板新建后发现如下错误: 解决方案 1. 打开C:\inetpub\wwwroot\wss\VirtualDirectories\,如下图: 2. 打开web.co ...

  3. Sharepoint2013 AD组用户不同步

    背景: SP2013列表库使用AD安全组授权访问,向AD安全组添加一个用户A,在Sharepoint AD同步(增量和完全)后,用户A仍然无法访问列表库:原因: 参考:安全令牌上的缓存  SP2013 ...

  4. 非RootLayer的隐式动画

    非RootLayer都有隐式动画,默认0.25秒. // 1.开启 [CATransaction begin]; // 2.设置关闭 YES-关闭:NO-开启 [CATransaction setDi ...

  5. Android DEX 基础

    转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/5736305.html本文出自[赵彦军的博客] 1.什么是dex? 简单说就是优化后的android版.exe ...

  6. Android窗口机制分析与UI管理系统

    类图关系 在看Android的窗口机制之前,先看看其主要的类图关系以及层级之间的依赖与调用关系 1.window在当前的android系统的中的呈现形式是PhoneWindow (frameworks ...

  7. 转 使用@Controller注解为什么要配置<mvc:annotation-driven />

    <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案.<mvc:annotation-dri ...

  8. 在Java中使用xpath对xml解析

    xpath是一门在xml文档中查找信息的语言.xpath用于在XML文档中通过元素和属性进行导航.它的返回值可能是节点,节点集合,文本,以及节点和文本的混合等.在学习本文档之前应该对XML的节点,元素 ...

  9. JSON金额解析BUG的解决过程

    [原创申明:文章为原创,欢迎非盈利性转载,但转载必须注明来源] 这是在我们开发的一个支付系统中暴露的一个BUG,问题本身比较简单,有意思的是解决问题的过程.将过程分享出来,希望能够对大家有所帮助. 一 ...

  10. jquery的几个常用方法

    第一部份关键词: .bind() .unbind() .css() .hasclass() .removeclass .parent() .children() .html() .hide() .sh ...