在Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Device detection和Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Site preference这两篇文章中已经对Spring Mobile
有过简单的介绍,这里介绍的是Spring Mobile
的第三种方法也是最优雅的一种方法:Device aware view
(设备自动感知视图)。
本文示例代码基于Spring Boot 2.2.7
、JDK1.8
。
全部代码Gitee
地址:https://gitee.com/qiwan/spring-mobile-demo
1.首先在pom.xml
中引用以下依赖:
<dependency>
<groupId>org.springframework.mobilegroupId>
<artifactId>spring-mobile-deviceartifactId>
<version>2.0.0.M3version>
dependency>
<repositories>
<repository>
<id>spring-milestonesid>
<name>Spring Milestonesname>
<url>https://repo.spring.io/libs-milestoneurl>
<snapshots>
<enabled>falseenabled>
snapshots>
repository>
repositories>
2.创建WebMvcConfig
类实现WebMvcConfigurer
接口,重写addInterceptors
和addArgumentResolvers
两个方法,注册Bean:LiteDeviceDelegatingViewResolver
,代码如下:
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.mobile.device.DeviceResolverHandlerInterceptor;
import org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor;
import org.springframework.mobile.device.site.SitePreferenceHandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DeviceResolverHandlerInterceptor());
registry.addInterceptor(new SitePreferenceHandlerInterceptor());
}
@Override
public void addArgumentResolvers(
List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new SitePreferenceHandlerMethodArgumentResolver());
}
@Bean
public LiteDeviceDelegatingViewResolver thymeleafViewResolver(ThymeleafProperties properties, SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
resolver.setCharacterEncoding(properties.getEncoding().name());
resolver.setContentType(appendCharset(properties.getServlet().getContentType(), resolver.getCharacterEncoding()));
resolver.setProducePartialOutputWhileProcessing(properties.getServlet().isProducePartialOutputWhileProcessing());
resolver.setExcludedViewNames(properties.getExcludedViewNames());
resolver.setViewNames(properties.getViewNames());
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
resolver.setCache(properties.isCache());
LiteDeviceDelegatingViewResolver delegate = new LiteDeviceDelegatingViewResolver(resolver);
delegate.setMobilePrefix("mobile/");
delegate.setTabletPrefix("tablet/");
delegate.setEnableFallback(true);
return delegate;
}
private String appendCharset(MimeType type, String charset) {
if (type.getCharset() != null) {
return type.toString();
}
LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
parameters.put("charset", charset);
parameters.putAll(type.getParameters());
return new MimeType(type, parameters).toString();
}
}
3.创建Controller
类并编写方法:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/")
public class AwareController {
@RequestMapping("aware")
public String aware() {
return "index";
}
}
4.三个index.html
页面所在的目录结构如下:
src/main/resources
--static
--templates
--mobile
index.html
--tablet
index.html
index.html
application.properties
启动服务并从多端浏览器发起请求,可发现方法跳转到了对应的页面。
备注:
1.Spring Boot
使用Thymeleaf
模版时,源码中指定的thymeleaf
视图解析器的Bean
名称为:thymeleafViewResolver
,且不能更改,故上面注册的Bean
名称需要指定为thymeleafViewResolver
。可使用@Bean(name="thymeleafViewResolver")
或者像上面代码里一样指定方法名称为thymeleafViewResolver
的方式。相关源码在spring-boot-autoconfigure-2.2.7.RELEASE.jar
包中,代码所在class
文件为:org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
,源码如下:
@Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver")
ThymeleafViewResolver thymeleafViewResolver(ThymeleafProperties properties,
SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
resolver.setCharacterEncoding(properties.getEncoding().name());
resolver.setContentType(
appendCharset(properties.getServlet().getContentType(), resolver.getCharacterEncoding()));
resolver.setProducePartialOutputWhileProcessing(
properties.getServlet().isProducePartialOutputWhileProcessing());
resolver.setExcludedViewNames(properties.getExcludedViewNames());
resolver.setViewNames(properties.getViewNames());
// This resolver acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
resolver.setCache(properties.isCache());
return resolver;
}
private String appendCharset(MimeType type, String charset) {
if (type.getCharset() != null) {
return type.toString();
}
LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
parameters.put("charset", charset);
parameters.putAll(type.getParameters());
return new MimeType(type, parameters).toString();
}
2.上面@Bean
注解的代码中有一部分代码拷自上面的源码,目的是为了使用我们在application.properties
文件中已经配置过的spring.thymeleaf.xxx
等相关配置。
本系列上一篇:
Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Site preference