• 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

  • 相关阅读:
    VsCode 各场景高级调试与使用技巧
    rust type
    解决Chrome浏览器控制台请求返回值中的中文显示为乱码的问题
    js 固定时间运行任务
    rust 泛型
    根据值选择
    js reload window.onerror
    rust 个例
    rust index
    rust return impl Trait
  • 原文地址:https://www.cnblogs.com/softidea/p/7831174.html
Copyright © 2020-2023  润新知