关于Controller继承Controller的效果与切面触发测试

发布时间:2023年12月20日

使用背景:如在多端开发时有时会共用同一套接口,但是需要对接口进行区分例访问多加一串url,并且不同端可能获取一些公用信息方式不一样,如pc是一个k值从redis拿取用户登录信息而手机端确实直接解析等等。
解决上述场景问题下列举例解决方案:
方案1:直接新建Controller加串url并继承原url(缺点是麻烦,虽然加url比较灵活但是一般情况下同一端的前边一段url是固定的),值得注意的点是,将子Controller下全部方法设置为切点时若访问未重写的父方法切面是不触发的,具体看下方测试。这里可以用拦截器解决不触发前置通知而无法赋值的问题。
方案2:整个过滤器对统一前缀进行过滤转发,并做一些操作。具体看下方。

关于继承Controller测试

首先创建一个Controller

@RestController
@RequestMapping(value="ceshi")
public class CeshiController {
    @GetMapping(value = "ceshi")
    public String ceshi() {
        return "测试";
    }
}

创建一个Controller继承上一个Controller

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
}

1.访问/to/ceshi/ceshi接口,得到返回值测试。

效果:
在这里插入图片描述

2.修改继承Controller如下(重写ceshi方法,但不修改Mapping注解)

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
    public String ceshi() {
        return "测试11";
    }
}

效果:
在这里插入图片描述

3.修改继承Controller如下(重写ceshi方法,修改Mapping注解)

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
    @GetMapping(value = "ceshi11")
    public String ceshi() {
        return "测试11";
    }
}

效果:
访问/to/ceshi/ceshi时报404
在这里插入图片描述
访问/to/ceshi/ceshi11时得到重写后返回值
在这里插入图片描述

4.修改继承Controller如下(不修改Mapping注解,把Mapping注解的方法改个名)

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
    @GetMapping(value = "ceshi")
    public String ceshi11() {
        return "测试11";
    }
}

效果:无法启动项目
在这里插入图片描述

关于继承Controller切面触发测试

创建一个切面,将继承Controller所有方法设置为切点

@Aspect
@Component
public class CeshiAspect {
    @Pointcut("execution(* ceshi.Controller.Ceshi2Controller.*(..))")
    public void demo() {}

    @Before("demo()")
    public void before(JoinPoint joinPoint){
        System.out.println("--------触发前置通知---------");
    }
}

1.测试未重写方法(不触发切面)

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
}

效果:
在这里插入图片描述

2.测试重写方法

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
    public String ceshi() {
        return "测试11";
    }
}

效果:

在这里插入图片描述
在这里插入图片描述

3.测试新增独有方法

@RestController
@RequestMapping(value="to/ceshi")
public class Ceshi2Controller extends CeshiController{
    @GetMapping(value = "ceshi222")
    public String ceshi() {
        return "测试222";
    }
}

效果:
在这里插入图片描述
在这里插入图片描述

补充:若不希望对方法进行重写,在访问接口时想要提前触发一些方法可使用拦截器。

过滤器转发

1.一个原Controller

@RestController
@RequestMapping(value="ceshi")
public class CeshiController {

    @GetMapping(value = "ceshi")
    public String ceshi(HttpServletRequest request) {
        String token = request.getHeader("token");
        System.out.println(token);
        return "测试";
    }
 }

2.过滤器工具

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CeshiFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        //可能需要请求转发到新的地址
        System.out.println("----------过滤----------");
        System.out.println("原:"+req.getRequestURI());
        System.out.println("新:"+req.getRequestURI().substring(3));
        //转发到req.getRequestURI().substring(3)
        request.getRequestDispatcher(req.getRequestURI().substring(3)).forward(request,response);
    }
}

3.注册过滤器

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CeshiConfigurer  implements WebMvcConfigurer {
    @Bean
    public FilterRegistrationBean jwtFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new CeshiFilter());
        registration.setName("CeshiFilter");
        //过滤to开头的url
        registration.addUrlPatterns("/to/*");
        registration.setOrder(1);
        return registration;
    }
}

访问/to/ceshi/ceshi并设置头信息token为11111
结果:
在这里插入图片描述
在这里插入图片描述
使用OpenFeign或是Gateway访问接口会出现头信息丢失的情况:解决方法详见:解决方法

文章来源:https://blog.csdn.net/qq_43840143/article/details/135102053
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。