@Valid@Validated差異
@Valid@Validated差異
@Valid
そのコアは
使用しているので自動構成.
動作原理
デフォルトでは、コントローラに
処理の有効性が検証された論理.
理由は?
処理する解析器、getArgumentResolver()を探しています.
を使用して確認できます.
この継承クラスのvalidateIfApplicableでは、ループを中心に操作が実行されます.
ある場合は、
認証エラーが発生すると、
これはスプリング
400個のエラーが吐き出されます.
@Validated
@Validated(グローバルコントローラに貼り付け)
上記の@Validとは異なり、cglibはAOPベースのメソッドリクエストである
インタフェースのように、JDKダイナミックエージェントではなくCglib proxyを使用します.
その後、ラインはプロキシリクエストの有効性検証をブロックします.
エラーメッセージのデフォルト値は
これは
500エラーと一緒に外に吐きます.また、
次に、私が実装したソースコードの例を示します.
SampleController.java
@Valid
@Valid
はJSR-303規格です.org.hibernate.validator.internal.constraintvalidators
体験値は、複数のValidator
によって実現される.そのコアは
LocalValidatorFactoryBean
で、スプリングを案内します.使用しているので自動構成.
動作原理
デフォルトでは、コントローラに
@Valid
がない場合でも処理の有効性が検証された論理.
理由は?
InvocableHandlerMethod
は、適切なパラメータプロセッサを見つけようとした.HandlerMethodArgumentResolverComposite
に送信されます.処理する解析器、getArgumentResolver()を探しています.
private final Map<MethodParameter, HandlerMethodArgumentResolver>argumentResolverCache = new ConcurrentHashMap<>(256);
この因子に含まれるRequestResponseBodyMethodProcessor
によってを使用して確認できます.
RequestResponseBodyMethodProcessor
彼はAbstractMessageConverterMethodArgumentResolver
を引き継いだ.この継承クラスのvalidateIfApplicableでは、ループを中心に操作が実行されます.
@Valid
があるかどうかを検索します.ある場合は、
DataBinder
オブジェクトに移動して検証します.認証エラーが発生すると、
MethodArgumentNotValidException
になります.これはスプリング
ExceptionResolver
のDefaultHandlerExceptionResolver
のおかげです.400個のエラーが吐き出されます.
@Validated
@Validated(グローバルコントローラに貼り付け)
上記の@Validとは異なり、cglibはAOPベースのメソッドリクエストである
MethodValidationInterceptor
は受け入れて処理する.SampleController
は普通類だからです.インタフェースのように、JDKダイナミックエージェントではなくCglib proxyを使用します.
その後、ラインはプロキシリクエストの有効性検証をブロックします.
Set<ConstraintViolation<Object>>result;
空いていなければConstraintViolationException
を投げます.エラーメッセージのデフォルト値は
javax.validation.constraints.XXX.message
propertiesで定義されます.これは
DefaultHandlerExceptionResolver
に登録されているオブジェクトではありません.500エラーと一緒に外に吐きます.また、
ExceptionHandler
を実現する必要がある.次に、私が実装したソースコードの例を示します.
SampleController.java
import javax.validation.Valid;
import javax.validation.constraints.Min;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@Validated
public class SampleController {
@PostMapping("/hello")
public String hello(@Valid @RequestBody MessageRequest messageRequest) {
log.info(messageRequest.getMessage());
return "hello";
}
@GetMapping("/hi")
public String hi(@Min(value = 1) int value) {
log.info(String.valueOf(value));
return "hi";
}
}
MessageRequest.javaimport javax.validation.constraints.NotNull;
import lombok.Getter;
@Getter
public class MessageRequest {
@NotNull(message = "message는 null일 수 없습니다.")
private String message;
}
SampleControllerTest.javaimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.lsj8367.web.request.MessageRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@WebMvcTest(SampleController.class)
class SampleControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext ctx;
@Autowired
private ObjectMapper objectMapper;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(ctx)
.alwaysDo(print())
.build();
}
@Test
@DisplayName("Post @Valid 테스트")
void test() throws Exception {
final String obj = objectMapper.writeValueAsString(new MessageRequest());
mockMvc.perform(post("/hello")
.content(obj)
.contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isBadRequest());
}
@Test
@DisplayName("Get @Validated 테스트")
void hiTest() throws Exception {
mockMvc.perform(get("/hi")
.param("value", "0")
.contentType(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isInternalServerError());
}
Reference
この問題について(@Valid@Validated差異), 我々は、より多くの情報をここで見つけました https://velog.io/@lsj8367/Valid-Validated-차이テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol