鉴于复杂页面自适应的难度,一般会做几套模板分别适应手机、平板、电脑等设备。使用 Spring Boot 开发单体应用时,一般会使用 Thymeleaf 模板,那么可以使用 AOP 技术来实现页面自适应。
如图所示,与普通项目相比而言,我们需要拦截用户的请求,获取 Request 中的 Header 的 User-Agent 属性,来判断用户的设备信息,然后修改 Controller 返回的页面路径,来适应设备的页面路径,从而达到页面自适应的效果。
代码实现
假设我们的静态资源目录如下
resources/
|-- mobile/
|-- index.html #手机版首页
|-- index.html #电脑版首页
1、添加 aop 的相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、定义设备的枚举类型 UserAgentTypeEnum.java
/**
* UserAgentType 枚举
*/
public enum UserAgentTypeEnum {
// 电脑
PC(0),
// 平板电脑
TABLET(1),
// 手机
PHONE(2);
private int code;
UserAgentTypeEnum(int code){
this.code = code;
}
public int getCode() {
return code;
}
}
3、添加 UserAgent 识别工具类
/**
* User-Agent 工具
*/
public class UserAgentTools {
/**
* 识别设备类型
* @param userAgent 设备标识
* @return 设备类型
*/
public static Integer recognize(String userAgent){
if(Pattern.compile("(Windows Phone|Android|iPhone|iPod)").matcher(userAgent).find()){
return UserAgentTypeEnum.PHONE.getCode();
}
if(Pattern.compile("(iPad)").matcher(userAgent).find()){
return UserAgentTypeEnum.TABLET.getCode();
}
return UserAgentTypeEnum.PC.getCode();
}
}
4、添加切面处理逻辑,实现设备识别和页面路径修改,假设 Controller 类包 cn.ictgu.controller 下
/**
* AOP 实现页面自适应
*/
@Aspect
@Component
@Log4j2
public class DeviceAdapter {
private static final String MOBILE_PREFIX = "mobile/";
/**
* 切入点:cn.ictgu.controller 下所有 @GetMapping 方法
*/
@Pointcut("execution(* cn.ictgu.controller..*(..)) && @annotation(org.springframework.web.bind.annotation.GetMapping)")
public void controllerMethodPointcut() {
}
/**
* 识别用户请求的设备并返回对应的页面
*/
@Around("controllerMethodPointcut()")
public String around(ProceedingJoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
try {
HttpServletRequest request = attributes.getRequest();
String userAgent = request.getHeader("User-Agent");
log.info(userAgent);
Integer deviceType = UserAgentTools.recognize(userAgent);
String path = (String) joinPoint.proceed();
return deviceType == UserAgentTypeEnum.PHONE.getCode() ? MOBILE_PREFIX + path : path;
} catch (Throwable e) {
e.printStackTrace();
}
}
throw new RuntimeException("DeviceAdapter,ServletRequestAttributes is null!");
}
}
5、至此,基于 AOP 的页面自适应就完成了。示例:
@GetMapping(value = "/index")
public String index() {
return "index";
}
手机访问就会得到 mobile/index.html
的页面,其他设备就会得到 index.html
的页面。
转载请注明出处,谢谢!
有兴趣一起写代码的,可以 加入我们,基于 Spring Boot 2.x 版本的最佳实践。项目及演示地址 http://im.ictgu.cn/
开源, 等你!
http://www.spring4all.com/article/169