当前位置: 首页 > 知识库问答 >
问题:

具有自定义HTTP错误响应的自定义ConstraintValidator消息

蓬运诚
2023-03-14

我正在努力裁剪javax。验证。ConstraintValidator和javax。验证。根据我的需要限制ValidatorContext。我从格式错误的请求正文收到的响应消息始终采用以下形状:

  • <代码>

此消息也以500而不是400错误请求的形式返回。我无法获得工作到解决方案来执行以下操作:

  1. 仅包括<代码>

我有以下代码:

import org.path.validation.ValidCreateThingRequest;
import org.path.service.ThingService;
// ... various other imports

  @PostMapping("/things")
  @ApiOperation(value = "Create a new thing")
  @ApiResponse(code = 201, message = "Newly created thing", response = Thing.class)
  @ResponseStatus(HttpStatus.CREATED)
  public ThingResponseProto createThing(
      @RequestBody @ValidCreateThingRequest final CreateThingRequestProto thingDto,
      final HttpServletRequest httpServletRequest) {
    final Context context = new RequestContext(httpServletRequest);
    final Thing createdThing = thingService.createThing(thingDto);
    return mapObjToProtoUtils.map(createdThing, ThingResponseProto.class);
  }
@Constraint(validatedBy = CreateThingRequestValidator.class)
@Target({ METHOD,PARAMETER })
@Retention(RUNTIME)
@Documented
public @interface ValidCreateThingRequest {
    String message() default "Request must be well-formed.";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
public class CreateCodeRequestValidator
    implements ConstraintValidator<ValidCreateThingRequest, CreateThingRequestProto> {

  private static final Pattern FORBIDDEN_NAME_CHARACTERS_REGEX =
      Pattern.compile("[\\\\/\\t\\n\\r\\f?;]");

  @Override
  public void initialize(ValidCreateCodeRequest constraintAnnotation) {};

  @Override
  public boolean isValid(final CreateThingRequestProto thingDto, ConstraintValidatorContext context) {
    return isValidCharacters(thingDto, context)
        && isValidNameExists(thingDto, context)
  }

  boolean isValidCharacters(final CreateThingRequestProto thingDto, ConstraintValidatorContext context) {
    final String name = thingDto.getName();

    if (FORBIDDEN_NAME_CHARACTERS_REGEX.matcher(name).find()) {
      context
          .buildConstraintViolationWithTemplate("Name must not contain forbidden characters.")
          .addConstraintViolation();
      return false;
    } else {
      return true;
    }
  }

  boolean isValidNameExists(final CreateThingRequestProto thingDto, ConstraintValidatorContext context) {
    final String name = thingDto.getName();

    if (name != null && !name.trim().isEmpty()) {
      context
          .buildConstraintViolationWithTemplate("Name must not be null or empty.")
          .addConstraintViolation();
      return false;
    } else {
      return true;
    }
  }
}

向上面的代码发送格式错误的有效负载将导致如下消息:

{
  error: "Internal Server Error",
  message: "createThing.thingDto: Request must be well-formed., createThing.thingDto: Name must not be null or empty.",
  path: "/things"
  status: 500
  timestamp: 1607110364124
}

我希望能够收到以下信息:

{
  error: "Bad Request",
  message: "Name must not be null or empty.",
  path: "/things"
  status: 400
  timestamp: 1607110364124
}

基于buildConstraintViolationWithTemplate(),这可能吗??

共有1个答案

许永年
2023-03-14

也许你可以使用@ControlllerAdments注释,比如

@ControllerAdvice
public class ConstraintValidatorExceptionHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    public void handleConstraintViolationException(ConstraintViolationException exception,
            ServletWebRequest webRequest) throws IOException {
        webRequest.getResponse().sendError(HttpStatus.BAD_REQUEST.value(), exception.getMessage());
    }
}   
 类似资料:
  • Apache可以让网站管理员自己自定义对一些错误和问题的响应。 自定义的响应可以定义为当服务器检测到错误或问题时才被激活。 如果一个脚本崩溃并产生"500 Server Error"响应,那么这个响应可以被更友好的提示替换或者干脆用重定向语句跳到其他的URL(本地的或外部的)。 行为 老式的行为 Apache1.3 会响应一些对于用户没有任何意义的错误或问题信息,而且不会将产生这些错误的原因写入日

  • 然而,这产生了(正如怀疑的那样)完全不同的反应:

  • 安全测试人员声称,我应该清理返回的JSON(即转义这些符号),因为这可能会给旧的浏览器带来一些问题(即在浏览器中执行此JS代码)。 但是生成错误消息的是SpringBoot框架, 我在这里没有太多的控制权。 当然,我可以将参数定义为String,并自己进行验证,但我怀疑这是否是正确的方法。我的参数定义为Integer,我希望它保持这种方式。 做这件事最简单的方法是什么?

  • 给Rest服务打电话 http://acme.com/app/widget/123 返回: 此客户端代码的工作原理是: 但是,http://acme.com/app/widget/456返回: 但此客户端代码引发了一个异常: 我试过: 第二次调用只是抛出了另一个HttpClientErrorException,而且它觉得调用服务两次是不对的。 是否有一种方法可以调用该服务一次,并在成功时将响应解析

  • 请帮助我了解我应该在哪里更新失败案例的实际合同?