【spring mvc】配置请求到视图名称转换器

最近在开发项目中遇到springmvc在进行视图渲染时,pc端和移动端不是同一个页面的情况,需要将不同的设备类型解析到不同的视图进行渲染。

一、配置方式

这里我写了一个RequestToViewNameTranslatorImpl类实现了RequestToViewNameTranslator接口,并重写了获取视图名称的方法。

java 复制代码
@Component(DispatcherServlet.REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME)
public class RequestToViewNameTranslatorImpl implements RequestToViewNameTranslator {

    private DefaultRequestToViewNameTranslator defaultRequestToViewNameTranslator = new DefaultRequestToViewNameTranslator();
    private DefaultRequestToViewNameTranslator mobileRequestToViewNameTranslator = new DefaultRequestToViewNameTranslator();
    public AuthserverRequestToViewNameTranslator() {
        mobileRequestToViewNameTranslator.setSuffix("_mobile");
    }

    @Override
    public String getViewName(HttpServletRequest request) throws Exception {
        if(getDeviceType(request) == DeviceType.MOBILE) {
            return mobileRequestToViewNameTranslator.getViewName(request);
        }
        return defaultRequestToViewNameTranslator.getViewName(request);
    }

    private DeviceType getDeviceType(HttpServletRequest request) {
        return UserAgent.parseUserAgentString(request.getHeader("User-Agent"))
                .getOperatingSystem()
                .getDeviceType();
    }
}

需要注意的是:

1、Bean的名称必须是viewNameTranslator

复制代码
(DispatcherServlet.REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME)

2、类中我使用了UserAgent获取了设备类型,需要引入jar包:

XML 复制代码
<dependency>
    <groupId>eu.bitwalker</groupId>
    <artifactId>UserAgentUtils</artifactId>
    <version>1.21</version>
</dependency>

二、原理

要了解此配置的实现机制需要看DispatcherServlet中的定义:

java 复制代码
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";


private void initRequestToViewNameTranslator(ApplicationContext context) {
    try {
       this.viewNameTranslator =
             context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
       if (logger.isDebugEnabled()) {
          logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]");
       }
    }
    catch (NoSuchBeanDefinitionException ex) {
       // We need to use the default.
       this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
       if (logger.isDebugEnabled()) {
          logger.debug("Unable to locate RequestToViewNameTranslator with name '" +
                REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME + "': using default [" + this.viewNameTranslator +
                "]");
       }
    }
}

当DispatcherServlet初始化时会调用initRequestToViewNameTranslator方法,此方法会从ApplicationContext中去查找名称为viewNameTranslator的Bean对象,做为请求转换成视图名称的对象。

java 复制代码
private void applyDefaultViewName(HttpServletRequest request, ModelAndView mv) throws Exception {
    if (mv != null && !mv.hasView()) {
       mv.setViewName(getDefaultViewName(request));
    }
}
protected String getDefaultViewName(HttpServletRequest request) throws Exception {
    return this.viewNameTranslator.getViewName(request);
}

applyDefaultViewName方法用于将请求转换成视图名称,需要注意的是,如果Controller中返回的有视图名称则不再使用请求获取视图名称。

相关推荐
YOU OU2 小时前
Spring IoC&DI
java·数据库·spring
小江的记录本4 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
云烟成雨TD5 小时前
Spring AI Alibaba 1.x 系列【58】Spring AI Alibaba Builtin Nodes 模块介绍
java·人工智能·spring
小江的记录本5 小时前
【Java基础】反射与注解:核心原理、自定义注解、注解解析方式(附《思维导图》+《面试高频考点清单》)
java·数据结构·python·mysql·spring·面试·maven
smileNicky6 小时前
Spring框架懒加载怎么实现?
python·spring·rpc
yychen_java7 小时前
IDEA × Qoder:告别“手写Spring”,进入AI协作开发新时代
人工智能·spring·intellij-idea
未若君雅裁7 小时前
Spring Bean 作用域、线程安全与生命周期
java·安全·spring
Ting-yu9 小时前
Spring AI Alibaba零基础速成(5) ---- Memory(记忆)
java·人工智能·后端·spring
月落归舟9 小时前
一文掌握Spring AOP:从入门到底层原理
java·后端·spring
XiYang-DING9 小时前
【Spring】SpringMVC
java·后端·spring