Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Device aware view

  在Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Device detection和Spring Boot中优雅的判断请求来源设备并跳转对应的页面-Site preference这两篇文章中已经对Spring Mobile有过简单的介绍,这里介绍的是Spring Mobile的第三种方法也是最优雅的一种方法:Device aware view(设备自动感知视图)。

  本文示例代码基于Spring Boot 2.2.7JDK1.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接口,重写addInterceptorsaddArgumentResolvers两个方法,注册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

你可能感兴趣的:(Spring,Boot,Spring,spring,boot,spring,spring,mobile)