Java 如何减少spring引导控制器中的重复代码
我刚刚开始使用SpringBoot来提供服务。我有几个控制器使用相同的代码在他们的身体。例如,在每个控制器中,我必须检查从请求获得的请求对象是否为null:Java 如何减少spring引导控制器中的重复代码,java,spring,spring-boot,Java,Spring,Spring Boot,我刚刚开始使用SpringBoot来提供服务。我有几个控制器使用相同的代码在他们的身体。例如,在每个控制器中,我必须检查从请求获得的请求对象是否为null: if (request == null){ throw new InvalidRequestException("the request object is null"); } 我知道在几个控制器中重复代码不是一个好方法,所以我想知道是否有办法防止代码重复,或者spring boot是否有解决上述问题的方法。只需将代码包装在一个方
if (request == null){
throw new InvalidRequestException("the request object is null");
}
我知道在几个控制器中重复代码不是一个好方法,所以我想知道是否有办法防止代码重复,或者spring boot是否有解决上述问题的方法。只需将代码包装在一个方法中:
protected void checkRequest(Object request){
if (request == null){
throw new InvalidRequestException("the request object is null");
}
}
并在
AbstractController
类中声明它。让您的控制器扩展此类。让您的服务层根据您的条件抛出自定义异常,并在抛出异常时在控制器中使用@ControllerAdvice来处理输出。一种方法是创建一个抽象类,该类将包含一个将由扩展层调用的包装方法控制器
public abstract class CoreController {
protected void validateRequest(MyRequest request) {
if (request == null) throw new InvalidRequestException("the request object is null");
}
}
使用此类扩展控制器并调用validateRequest
方法
public class MyController extends CoreController {
@PostMapping("/some_endpoint")
public MyResponse endpointMethod (@RequestBody MyRequest request) {
validateRequest(request);
...
return new MyResponse();
}
}
基本上,您所做的是参数验证。这是一种横切关注点,是使用AOP方法的完美用例 Spring提供了非常好的方法来实现这一点 您可以像这样简单地使用
@validate
@PostMapping
public ResponseEntity<Void> someMEthod(@Validated(CustomChecks.class) @RequestBody request yourRequest)
@PostMapping
公共响应属性someMEthod(@Validated(CustomChecks.class)@RequestBody request yourRequest)
然后可以将所有验证逻辑放入CustomChecks类中。(您可以找到大量示例)
如果您有非常小的通用验证,那么您也可以使用注释
在您的情况下,只需在请求类上添加@NotNull注释即可。检查这个
希望这对您使用SpringBoot有所帮助,因此在您的应用程序中,在您定义
@SpringBootApplication
注释的地方,您可以指定下一个@Bean
:
@Bean
public HttpRequestHandler httpRequestHandler () {
return new MyHttpRequestHandler();
}
还可以创建MyHttpRequestHandler
类,在该类中,您可以使用该类生成任何逻辑:
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request == null) {
throw new InvalidRequestException("the request object is null");
}
}
}
春季AOP
创建如下所示的方面类:
@Aspect
class AopDemo{
@Around("execution(* com.demo.controller.*(..))")
public Object release(JoinPoint jp){
try{
Object[] args = jp.getArgs();
for(Object arg: args){
if(arg == null){
throw new InvalidRequestException("the request object is null");
}
}
return jp.proceed(args);
}catch(InvalidRequestException ire){
// handle InvalidRequestException
}catch(Exception ex){
// handle Exception
}
}
}
我同意@Niraj Sonawane使用@Validated注释来处理文章中给出的具体案例
此外,使用过滤器可能是处理“执行控制器操作的先决条件”情况的另一种选择。我们使用复杂的逻辑来解决设计中所有控制器所需的访问权限。我们使用了一个过滤器来处理这个问题。最好使用@Valid来检查有效负载,而不用手动检查。请按照下面的解释 您可以使用“导入org.springframework.validation.Errors;”和@Valid,如下所示
@PostMapping("/test")
public ResponseEntity<String> editStatus(@Valid @RequestBody Person person, Errors errors) {
String responseMessage;
if(errors.hasErrors()) {
responseMessage = "'" + errors.getFieldError().getField() + "' " + errors.getFieldError().getDefaultMessage();
} else {
// You can do ur logic here
responseMessage = "result";
}
return ResponseEntity.accepted().body(responseMessage);
}
public class Person {
@NotNull
private String firstName;
@NotNull
private String lastName;
private String city;
//Getter
//Setter
}
在这个解释中,我使用了Person有效负载@Valid检查有效负载内容。一旦您收到没有必填字段的有效负载,您可以使用错误处理这种情况您可以提供控制器的示例,特别是关于该请求对象来自何处的示例吗?您通常会使用包含公共代码的方法。但是对于这个具体的例子,请求怎么可能是空的呢?对于这种特殊情况,使用Bean验证和
@RequestBody@Valid MyObject request
。