Spring拦截机制之后端国际化心得
需求
前端请求的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中配置,为所有beanName以Controller为后缀的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>
要点分析
- 表面上,该方案很好地实现了对所有beanName以Controller为后缀的bean进行拦截,没有方案二浪费系统资源的弊端。
- 但是,无法保证开发人员自行编写的其他bean就不会以Controller为后缀
- 同时,无法保证开发人员编写的Controller类就一定是以Controller为beanName后缀
- 我们知道,编写的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拦截机制之后端国际化心得的更多相关文章
- 使用方法拦截机制在不修改原逻辑基础上为 spring MVC 工程添加 Redis 缓存
首先,相关文件:链接: https://pan.baidu.com/s/1H-D2M4RfXWnKzNLmsbqiQQ 密码: 5dzk 文件说明: redis-2.4.5-win32-win64.z ...
- 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了
折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...
- 两个开源的 Spring Boot + Vue 前后端分离项目
折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...
- spring拦截器中修改响应消息头
问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...
- Spring 拦截器实现+后台原理(HandlerInterceptor)
过滤器跟拦截器的区别 spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的.这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成 ...
- Hibernate工作原理及为什么要用?. Struts工作机制?为什么要使用Struts? spring工作机制及为什么要用?
三大框架是用来开发web应用程序中使用的.Struts:基于MVC的充当了其中的试图层和控制器Hibernate:做持久化的,对JDBC轻量级的封装,使得我们能过面向对象的操作数据库Spring: 采 ...
- Spring Filter过滤器,Spring拦截未登录用户权限限制
转载自:http://pouyang.iteye.com/blog/695429 实现的功能:判断用户是否已登录,未登录用户禁止访问任何页面或action,自动跳转到登录页面. 比较好的做法是不管什 ...
- spring工作机制及为什么要用?
spring工作机制及为什么要用?1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作.2.DispatcherSer ...
- Spring(五)Spring缓存机制与Redis的结合
一.Redis和数据库的结合 使用Redis可以优化性能,但是存在Redis的数据和数据库同步的问题. 例如,T1时刻以将 key1 保存数据到 Redis,T2时刻刷新进入数据库,但是T3时刻发生了 ...
随机推荐
- 解决mysql too many connections的问题
由于公司服务器上的创建的项目太多,随之创建的数据库不断地增加,在用navicat链接某一个项目的数据库时会出现too many connections ,从而导致项目连接数据库异常,致使启动失败. 为 ...
- Java使用实现面向对象编程:第七章集合框架的解读=>重中之重
对于集合框架,是非常重要的知识,是程序员必须要知道的知识点. 但是我们为什么要引入集合框架呢? 我们之前用过数组存储数据,但是采用数组存储存在了很多的缺陷.而现在我们引用了集合框架,可以完全弥补了数组 ...
- MySQL大数据优化
我们考虑的情况是在你的数据量很大的情况下,千万级别的数据量.不要当我们的请求响应时间已经让我无法忍受的时候,再来想起来优化,可能有点迟了.因为可能会丢失很多潜在的价值客户.所以,在我们当初设计表,或者 ...
- 【代码笔记】iOS-验证手机号,邮箱,车牌号是否合法
一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...
- DXGI 1.5新特性
为了支持更具弹性和的输出设定和副本机制,DXGI1.5添加了下面这些功能: 高动态范围(HDR)和宽色域(WCG) 可变刷新率显示 复制输出 奉献和再生资源 高动态范围(HDR)和宽色域(WCG) H ...
- git分布式版本控制玩法
git分布式版本控制玩法 Git distributed version control play github的配置安装步骤:1.下载git bash(从http://www.git-scm.com ...
- HTML最新标准HTML5小结
写在前面 HTML5出来已经很久了,然而由于本人不是专业搞前端的,只知道有这个东西,具体概念有点模糊(其实就是一系列标准规范啦):因此去年(2015.11.09),专门对HTML5做了个简单的小结,今 ...
- EA方法论
1 EA的定义 Enterprise Architecture,企业架构,简称EA.根据开放群组的业务领导层IT架构指引:“有效的企业架构(Enterprise Architecture,EA)对企业 ...
- android socket 线程连接openwrt与arduino单片机串口双向通信
package zcd.netanything; import java.io.BufferedReader; import java.io.InputStreamReader; import jav ...
- 通过XShell链接虚拟机的CentOS
今天在Win7环境通过XShell链接VirtualBox的CentOS;始终链接不上,原来是因为虚拟机选择网络链接方式不对[推荐连接方式:Host-only Adapter(主机模式). 知识提要: ...