Spring Boot 使用 AOP 实现页面自适应
鉴于复杂页面自适应的难度,一般会做几套模板分别适应手机、平板、电脑等设备。使用 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
Spring Boot 使用 AOP 实现页面自适应的更多相关文章
- spring boot使用AOP切面编程
spring boot使用AOP 1.在pom文件中添加依赖: <!--spring boot aop切面--> <dependency> <groupId>org ...
- Spring Boot + thymeleaf 后台与页面(二)
Spring Boot推荐使用thymeleaf模板完成与页面的交互(已不支持JSP某些特性,不推荐JSP) 步骤 在一个Spring Boot Web项目基础上,也可以参考我前一篇文章建立的项目 1 ...
- Spring Boot学习——AOP编程的简单实现
首先应该明白一点,AOP是一种编程范式,是一种程序设计思想,与具体的计算机编程语言无关,所以不止是Java,像.Net等其他编程语言也有AOP的实现方式.AOP的思想理念就是将通用逻辑从业务逻辑中分离 ...
- spring boot 中AOP的使用
一.AOP统一处理请求日志 也谈AOP 1.AOP是一种编程范式 2.与语言无关,是一种程序设计思想 面向切面(AOP)Aspect Oriented Programming 面向对象(OOP)Obj ...
- Spring Boot 使用 Aop 实现日志全局拦截
前面的章节我们学习到 Spring Boot Log 日志使用教程 和 Spring Boot 异常处理与全局异常处理,本章我们结合 Aop 面向切面编程来实现全局拦截异常并记录日志. 在 Sprin ...
- Spring Boot使用AOP的正确姿势
一.为什么需要面向切面编程? 面向对象编程(OOP)的好处是显而易见的,缺点也同样明显.当需要为多个不具有继承关系的对象添加一个公共的方法的时候,例如日志记录.性能监控等,如果采用面向对象编程的方法, ...
- Spring MVC或Spring Boot配置默认访问页面不生效?
相信在开发项目过程中,设置默认访问页面应该都用过.但是有时候设置了却不起作用.你知道是什么原因吗?今天就来说说我遇到的问题. 首先说说配置默认访问页面有哪几种方式. 1.tomcat配置默认访问页面 ...
- Spring Boot 系列教程11-html页面解析-jsoup
需求 需要对一个页面进行数据抓取,并导出doc文档 html解析器 jsoup 可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于JQuery的操 ...
- Spring Boot使用AOP在控制台打印请求、响应信息
AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等. AOP简介 AOP全称Aspect Oriented Programming,面向切面,AOP主要实现的 ...
随机推荐
- Android开发概要记录
1..o文件. .ko和.so文件的路径 \kernel\out\mediatek---------------.o文件 .c/.cpp文件编译生成的目标文件 \out\target\product\ ...
- Android特效专辑(十一)——仿水波纹流量球进度条控制器,实现高端大气的主流特效
Android特效专辑(十一)--仿水波纹流球进度条控制器,实现高端大气的主流特效 今天看到一个效果挺不错的,就模仿了下来,加上了一些自己想要的效果,感觉还不错的样子,所以就分享出来了,话不多说,上图 ...
- linux设备驱动模块引用和依赖
/modules/04 # lsmod test 787 0 - Live 0xbf010000 (PO) func 633 1 test, Live 0xbf00c000 (PO) test -&g ...
- linux下64位汇编的系统调用(4)
经过上一篇的铺垫貌似可以很轻松的用汇编写出mmap的代码来,可仔细一看,还是有不少问题需要解决: 1.系统调用mmap如果出错并不直接返回MAP_FAILED(-1),而是一个"类似&quo ...
- MongoDB学习笔记(四)
第四章 Mongodb聚合函数 插入 测试数据 for(var j=1;j<3;j++){ for(var i=1;i<3;i++){ var person={ Name:"ja ...
- 快递单号查询免费api接口(PHP示例)
快递单号查询API,可以对接顺丰快递查询,邮政快递查询,中通快递查询等.这些快递物流企业,提供了快递单号自动识别接口,快递单号查询接口等快递物流服务.对于电商企业,ERP服务企业,集成此接口到自己的软 ...
- jstack Dump
jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注) 执行中,Runnable 等待资源,Waiting on conditio ...
- JavaScript对象添加、删除、修改对象的属性
https://www.cnblogs.com/goweb/p/5357640.html 利用动态特性 function Person(){}; var person = new Person(); ...
- Python人工智能之-三大数学难点 !
1. 微积分: 定积分与不定积分.全微分.最小二乘法.二重积分.微分方程与差分方程等... 2. 线性代数: 行列式.矩阵.向量.线性方程组.矩阵的特性和特性向量.二次型等... 3. 概率论和统计学 ...
- VirtualBox上安装64位系统
http://blog.csdn.net/mal327/article/details/6597263 原来VirtualBox安装64位的系统需要满足以下条件: 1.64位的cpu2.安装的系统必须 ...