Spring Boot 使用 AOP 实现页面自适应

简介: 鉴于复杂页面自适应的难度,一般会做几套模板分别适应手机、平板、电脑等设备。使用 Spring Boot 开发单体应用时,一般会使用 Thymeleaf 模板,那么可以使用 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

相关文章
|
6天前
|
SQL 监控 Java
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
这篇文章介绍了如何在IDEA和Spring Boot中使用AOP技术实现日志信息的记录到数据库的详细步骤和代码示例。
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
|
4天前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
1月前
|
Java Spring
在Spring Boot中使用AOP实现日志切面
在Spring Boot中使用AOP实现日志切面
|
4天前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
4天前
|
Java Spring 容器
SpringBoot整合AOP实现打印方法执行时间切面
SpringBoot整合AOP实现打印方法执行时间切面
11 1
|
5天前
|
XML SQL JavaScript
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
这篇文章介绍了如何在Vue页面中结合SpringBoot、MyBatis、ElementUI和ECharts,实现从数据库获取数据并展示为图表的过程,包括前端和后端的代码实现以及遇到的问题和解决方法。
在vue页面引入echarts,图表的数据来自数据库 springboot+mybatis+vue+elementui+echarts实现图表的制作
|
5天前
|
存储 前端开发 JavaScript
Springboot+Vue实现将图片和表单一起提交到后端,同时将图片地址保存到数据库、再次将存储的图片展示到前端vue页面
本文介绍了使用Springboot后端和Vue前端实现图片与表单数据一起提交到后端,并保存图片地址到数据库,然后展示存储的图片到前端Vue页面的完整流程。
Springboot+Vue实现将图片和表单一起提交到后端,同时将图片地址保存到数据库、再次将存储的图片展示到前端vue页面
|
6天前
|
前端开发 Java Spring
springboot+thymeleaf+bootstrap 超级无敌简洁的页面展示 商城管理页面
这篇文章展示了一个使用Spring Boot、Thymeleaf和Bootstrap框架开发的简洁、响应式的商城管理页面,包括美食介绍、产品详情、购物车等功能,适合初学者学习和使用。
springboot+thymeleaf+bootstrap 超级无敌简洁的页面展示 商城管理页面
|
6天前
|
Java 数据库 Spring
springboot+thymeleaf中前台页面展示中、将不同的数字替换成不同的字符串。使用条件运算符
这篇文章介绍了如何在Spring Boot和Thymeleaf框架中使用条件运算符来根据数字字段的值动态替换显示不同的字符串,例如将订单状态的数字0和1替换为"未付款"和"已付款"等。
springboot+thymeleaf中前台页面展示中、将不同的数字替换成不同的字符串。使用条件运算符
|
6天前
|
安全 Java 开发者
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
14 1