我正在使用spring启动版本:2.0.5
格雷德尔:
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'io.reflectoring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-validation')
implementation('org.springframework.boot:spring-boot-starter-web')
runtimeOnly('com.h2database:h2')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.junit.jupiter:junit-jupiter-engine:5.0.1')
// these dependencies are needed when running with Java 11, since they
// are no longer part of the JDK
implementation('javax.xml.bind:jaxb-api:2.3.1')
implementation('org.javassist:javassist:3.23.1-GA')
}
test{
useJUnitPlatform()
}
控制器
@RestController
class ValidateRequestBodyController {
@PostMapping("/validateBody")
ResponseEntity<String> validateBody(@Valid @RequestBody Input input) {
return ResponseEntity.ok("valid");
}
}
验证器类
class InputWithCustomValidator {
@IpAddress
private String ipAddress;
// ...
}
class IpAddressValidator implements ConstraintValidator<IpAddress, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
Pattern pattern =
Pattern.compile("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$");
Matcher matcher = pattern.matcher(value);
//step 1
if (!matcher.matches()) {
return 400;
}
//Step 2
if (ipAddress already in DB) {
return 409; //conflict with other IP address
}
//Also I need to return different exception based on diff validations
}
}
控制器建议
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse> handle(ValidationException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(e.getMessage());
}
如果我从验证器中抛出customException,那么尽管我有相应的controllerAdvice,
{
"code": "invalid_request"
"description": "HV000028: Unexpected exception during isValid call."
}
总是,我收到400个坏的请求,因为我有一个controllerAdvice总是返回400。
我想在这里实现的是,有没有可能返回带有状态代码的customException或者有没有从Validator返回不同的状态代码?我在StackOverflow看到了类似的帖子,但是没有答案。我也查了其他的帖子,但没有发现有用。
在模型包下为错误创建一个类
@NoArgsConstructor
@Geeter
@Setter
public class ErrorMessage
{
private int errorCode;
private String errorMsg;
private String documentation;
public ErrorMessage(int errorCode,String errorMsg,String documentation)
{
this.errorCode=errorCode;
this.errorMsg=errorMsg;
this.documentation=documentation;
}
}
在异常包下创建自定义验证异常类
public class CustomValidationException extends RuntimeException
{
public CustomValidationException(String msg)
{
super(msg);
}
}
在同一(exception)包下创建ExceptionHandler类
@RestControllerAdvice
public class CustomValidationExceptionHandler
{
@ExceptionHandler
public ResponseEntity toResponse(CustomValidationException ex)
{
ErrorMessage errorMessage=new
ErrorMessage(400,ex.getMessage,"www.stackoverflow.com");
return new ResponseEntity<ErrorMessage>(errorMessage,HttpStatus.BAD_REQUES);
}
}
当前行为
>
当验证器代码抛出一个异常(它不扩展ConstraintDeclarationException
)而不是返回false时,javax.validation
将异常包装在ValidationException
中。这是验证者框架的行为,而不是spring框架的问题。
当验证器代码抛出扩展ConstraintDeclarationException
的异常而不是返回false时,javax.validation
框架会传播它。
如果验证器返回false而不是抛出异常,spring会将所有验证错误转换为全局错误
或字段错误
并将其包装在MethodArgumentNotValidexception
中并抛出。
问题
validationexception
中,因此不可能使用特定于异常的处理程序。可能的解决办法
ConstraintDeclarationException
的特定异常,并对其进行映射 @ExceptionHandler(ValidationException.class)
public ResponseEntity handle(ValidationException e) {
Throwable cause = e.getCause();
if (cause instanceof InvalidIpException) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)//may be different code
.body(cause.getMessage());
}
if (cause instanceof InuseIpException) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)//may be different code
.body(cause.getMessage());
}
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(e.getMessage());
}
ConstraintDeclarationException
,然后为其设置特定的处理程序。 public class InvalidIpException extends
ConstraintDeclarationException {
@ExceptionHandler(InvalidIpException.class)
public ResponseEntity handle(InvalidIpException e) {
...
}
参考代码
我正在处理WebAPI 2中的一个服务,endpoint当前返回一个<code>IHttpActionResult<code>。我想返回一个状态代码,但由于它不在枚举中,我不知道如何发送它,因为所有构造函数都需要一个参数 目前,我正在返回<code>BadResult(消息),但返回<code>422
我考虑在项目中使用fluent-http。 所以我尝试注入: 返回正确的字符串,但似乎没有使用状态代码。在这两种情况下,响应都有一个代码HTTP200。 注意:我发现一些状态代码是预先实现的: null
在Spring MVC@RequestMapping注释中,我返回JSP页面名称作为结果。这将返回HTTP状态代码200OK。如何将此状态代码更改为创建的201? @ResponseStatus不起作用。另外,HttpServletResponse也不能工作,因为我只需要返回自定义JSP页面。
在Spring Boot控制器中,我使用检查用户是否登录(使用基本auth+)。 但是如果用户没有登录,即他们没有经过身份验证,控制器返回。 根据我对身份验证与授权的了解,用于身份验证,而用于授权。 根据我的理解,总是检查用户的授权(顾名思义),但是有什么方法可以根据我们传递给它的参数自定义它,即? 我知道还有另一种解决方案:在中使用基于URL的安全配置,但如果我不想这样做,该怎么办。 有什么想法
我试图为web api控制器中的GET方法返回一个状态代码304 not modified。 我成功的唯一方法是这样的: 这里的问题是,它并不是一个例外,它只是没有被修改,所以客户端缓存是可以的。我还希望返回类型为User(正如所有web api示例使用GET显示的那样),而不是返回HttpResponseMessage或类似的内容。
问题内容: 我看到了一些类似的问题(像这样),但是没有一个问题专门解决这个问题。 因此,Google 现在支持SPA,并且大多数网络浏览器都支持HTML5 pushState 。 我的AngularJS(但可能是任何JS东西)网站都使用URL来确定API路由。然后执行API调用,然后相应地呈现内容。 但是,由于 每个URL都 返回HTTP 200状态代码(包括example.com/get-fre