繁体   English   中英

Spring REST 从路由获取控制器 + 方法?

[英]Spring REST get controller + method from route?

是否有内置的 Spring 方式说给我“/customers/a”(/customers/{id})的 RestController + 方法? 即执行标准的弹簧路由,但知道将调用哪个类/方法?

我试图在一个中心位置根据路线确定该方法是否具有特定注释。 用于集中请求/响应日志记录。

我可以遍历其余控制器的应用程序并自己构建地图,但想知道是否已经暴露了任何东西来知道请求会去哪里?

谢谢。

您可以使用 Spring AOP 模块。 我认为一种干净的方法(在不中断 RestController 端点流的情况下管理响应)可以是以下内容。

首先添加spring-boot-starter-aop 依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

让我们看看代码。

这是我们的ExampleRequest

import lombok.Data;

@Data
public class ExampleRequest {
    String name;
}

我们假设我们想要验证我们的请求 -> 如果 name == "anonymous" 我们想要返回一个 HTTP 状态 BAD_REQUEST。


这是我们的TestController

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {
    @Anonymous
    @GetMapping("")
    public ResponseEntity<String> test(ExampleRequest exampleRequest, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        else return new ResponseEntity<>(HttpStatus.OK);
    }    
}

我们将作为我们的请求的BindingResultBindingResult将使用的ExampleRequest作为参数传递。 无论如何,如果 bindingResult 有错误,我们的验证逻辑就会被破坏,所以我们需要返回我们想要的错误!

@Anonymous是我们的自定义注解,我们将使用它来告诉我们的 Advice(s) 哪些方法,或者更好 - 哪些类(Aspect 是“代理”的整个类),我们想要代理

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Anonymous {

}  

还有我们的TestAspect

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;

@Aspect
@Component
public class TestAspect {

    @Before(value = "@annotation(Anonymous) && args(exampleRequest, bindingResult,..)", argNames = "joinPoint,exampleRequest,bindingResult")
    public Object logExecutionTime(JoinPoint joinPoint, ExampleRequest exampleRequest, BindingResult bindingResult) throws Throwable {
        if (exampleRequest.getName().equals("anonymous")) bindingResult.rejectValue("name", "incorrect");
        return joinPoint;
    }

}   

我们要说的是:执行带有这些参数的定义ANONYMOUS注释的每个方法之前,执行此逻辑!

显然,您将拥有自定义的验证逻辑,因此请实施它。


正如我在上面的评论中所说的那样,我认为您可以直接从代理类返回错误,但同时我认为这个示例是使用 AOP 的更简洁的方式(使用 BindingResult 端点的流程受到尊重,这种技术确实如此) t 破坏模型类的其他验证。你可以使用 javax 验证,例如混合在建议中,一切都会完美地工作!),我个人喜欢这个 Spring AOP 模块,但不要滥用它

供参考: https : //docs.spring.io/spring/docs/2.5.x/reference/aop.html

您可能想尝试另一种方法:

使用 spring 支持的面向方面编程。 创建一个方面,作为所有控制器的拦截器。 Advice 将在实际的 rest 方法之前(或“代替”,取决于建议的类型)被调用,以便您能够获得访问权限,然后将执行转发给真正的控制器。 在方面的代码中,您可以内省要在真实控制器上调用的方法并确定它是否具有注释。

我发现正是这样的例子在这里(你得稍微改变一点的界定,以使纵横适用于您所选择的其他控制器)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM