だから私はカスタムバリデーターを持っていて、return
値をfalse
に設定すると機能します-
import com.vhealth.api.service.UserService;
import com.vhealth.api.utils.exceptions.InvalidPayloadException;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class UserNameUniqueValidator implements ConstraintValidator<UserNameUnique, String> {
@Autowired
UserService userService;
@Override
public void initialize(UserNameUnique constraintAnnotation) {
}
@Override
public boolean isValid(String userName, ConstraintValidatorContext context) {
if (userService.findByUserName(userName) != null) {
throw new InvalidPayloadException("Creating user requires unique userName new");
//return false;
}
return true;
}
}
しかし、そのセクションで例外をスローしようとすると、カスタム例外が原因で問題が発生するというエラーが発生します。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ValidationException: Unexpected exception during isValid call
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:932)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.Java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:688)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:801)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.Java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:770)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.Java:168)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:136)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.Java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.Java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.Java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.Java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.Java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.Java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.Java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.Java:201)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.Java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.Java:136)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.Java:134)
at com.vhealth.api.controller.ApiUserControllerTest.shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName(ApiUserControllerTest.Java:53)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.Java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.Java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.Java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.Java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.Java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.Java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.Java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.Java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.Java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.Java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.Java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.Java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.Java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.Java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.Java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.Java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.Java:63)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:120)
Caused by: javax.validation.ValidationException: Unexpected exception during isValid call
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.Java:281)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.Java:153)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.Java:117)
at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.Java:84)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.Java:452)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.Java:397)
at org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.Java:361)
at org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.Java:313)
at org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.Java:139)
at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.Java:102)
at org.springframework.validation.DataBinder.validate(DataBinder.Java:772)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.validate(RequestResponseBodyMethodProcessor.Java:115)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.Java:101)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.Java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.Java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:123)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:920)
... 68 more
Caused by: com.vhealth.api.utils.exceptions.InvalidPayloadException: Creating user requires unique userName new
at com.vhealth.api.utils.validators.UserNameUniqueValidator.isValid(UserNameUniqueValidator.Java:22)
at com.vhealth.api.utils.validators.UserNameUniqueValidator.isValid(UserNameUniqueValidator.Java:11)
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.Java:278)
... 90 more
例外は@Controller ExceptionResolover
@ExceptionHandler(InvalidPayloadException.class)
public ResponseEntity handleEmptyFieldException(InvalidPayloadException ex) {
return new ResponseEntity(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
編集:InvalidPayloadException
でUserNameUniqueValidator
例外をスローするとカスタムメッセージが返されるため、BindingResult
からのデフォルトメッセージの抽出にメインコントローラーでvalidaor
を使用しないようにします
カスタムメッセージを表示する場合は、次のコードを試してください。
@Override
public boolean isValid(String userName, ConstraintValidatorContext context) {
if (userService.findByUserName(userName) != null) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate("User " + userName + "already exists!")
.addConstraintViolation();
return false;
}
return true;
}
コンパイラエラーが発生していますか。スローされたエラーを確認してください
Caused by: com.vhealth.api.utils.exceptions.InvalidPayloadException: Creating user requires unique userName new
at com.vhealth.api.utils.validators.UserNameUniqueValidator.isValid(UserNameUniqueValidator.Java:22)
at com.vhealth.api.utils.validators.UserNameUniqueValidator.isValid(UserNameUniqueValidator.Java:11)
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.Java:278)
... 90 more
あなたが投げた例外がネストされた例外であることを意味しているだけだと思います
また、com.vhealth.api.controller.ApiUserControllerTest.shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName(ApiUserControllerTest.Java:53)でスタックトレースを確認してください
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.ValidationException: Unexpected exception during isValid call
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:932)
Nullではないチェックを追加できます!あなたはまだ[mchrobok]の答えに従うことができます。
@Override
public boolean isValid(String userName, ConstraintValidatorContext context) {
if (userService !=null && userService.findByUserName(userName) != null) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate("User " + userName + "already exists!")
.addConstraintViolation();
return false;
}
return true;
}