Spring Boot 2.0.1中Thymeleaf与LiteDeviceDelegatingViewResolver无法协同工作
实现Spring Boot + Thymeleaf的PC/移动端自动适配
要实现同一URL自动映射到PC或移动端页面,我们可以通过设备识别拦截器 + 动态视图名称解析的方式来完成,以下是具体步骤:
1. 可选:引入更精准的设备识别依赖
如果想要更准确的设备判断(比如区分手机、平板),可以引入UserAgentUtils库,当然也可以自己写简单的UA匹配逻辑:
<dependency> <groupId>eu.bitwalker</groupId> <artifactId>UserAgentUtils</artifactId> <version>1.21</version> </dependency>
2. 编写设备识别拦截器
创建一个拦截器,解析请求的User-Agent判断设备类型,再动态修改视图名称前缀:
import eu.bitwalker.useragentutils.DeviceType; import eu.bitwalker.useragentutils.UserAgent; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class DeviceInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 解析请求头中的User-Agent UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); DeviceType deviceType = userAgent.getOperatingSystem().getDeviceType(); // 把手机、平板归为移动端,其他归为PC端 String deviceFlag = (deviceType == DeviceType.MOBILE || deviceType == DeviceType.TABLET) ? "mobile" : "pc"; // 将设备类型存入请求属性,供后续视图解析使用 request.setAttribute("deviceType", deviceFlag); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception { // 如果有视图需要解析,自动给视图名加上设备前缀 if (modelAndView != null && modelAndView.getViewName() != null) { String originalView = modelAndView.getViewName(); String deviceType = (String) request.getAttribute("deviceType"); modelAndView.setViewName(deviceType + "/" + originalView); } } }
3. 注册拦截器到Spring配置
创建WebMvc配置类,把拦截器注册到Spring容器,让它对所有请求生效:
import org.springframework.context.annotation.Configuration; 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 DeviceInterceptor()).addPathPatterns("/**"); } }
4. 组织Thymeleaf模板结构
在src/main/resources/templates目录下,分别创建pc和mobile文件夹,存放对应端的页面:
templates/ ├── pc/ │ ├── index.html # PC端首页 │ └── about.html # PC端关于页 └── mobile/ ├── index.html # 移动端首页 └── about.html # 移动端关于页
5. 编写Controller
Controller只需要返回统一的视图名称即可,拦截器会自动帮我们加上设备前缀:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class PageController { @GetMapping("/") public String home() { // 拦截器会自动转为 pc/index 或 mobile/index return "index"; } @GetMapping("/about") public String about() { // 拦截器会自动转为 pc/about 或 mobile/about return "about"; } }
6. 测试验证
启动项目后,用PC浏览器访问http://localhost:8080/会加载pc/index.html;切换到手机浏览器或Chrome的移动端调试模式访问,就会自动加载mobile/index.html,完美实现同一URL自动适配不同端页面。
内容的提问来源于stack exchange,提问作者RobinZheng
相关产品推荐
相关产品推荐

