#java #spring #spring-boot #validation
#java #spring #spring-boot #проверка
Вопрос:
У меня есть этот сервисный метод, который вызывает метод repo, который, в свою очередь, генерируется spring:
Метод обслуживания:
public User findUserByEmail(String email) {
try {
Assert.notNull(email,"email is null!");
Optional<User> userOptional = userRepo.findUserDAOByEmail(email);
return userOptional.orElseThrow();
}
catch (...){
...
}
}
Репозиторий:
public interface UserRepo extends JpaRepository<User, Long> {
Optional<User> findUserByEmail(String email);
}
Я хотел, чтобы метод repo выдавал в IllegalArgumentException
качестве своих друзей (методы, которые выходят из коробки с Jparepository
do), но вместо этого он принял нулевой параметр «email» и искал его в базе данных и вернул результат, в котором такого пользователя не существует (p.s.: электронная почта ограниченане null в моей схеме)
Так я и сделал Assert.notNull(email,"email is null!");
Но мне интересно, есть ли лучший способ проверить, что «email» не равен null?
Ответ №1:
Ограничение также может быть наложено на параметр следующим образом —
@Validated
@Repository
public interface UserRepo extends JpaRepository<User, Long> {
Optional<User> findUserByEmail(@NotNull String email);
}
@Validated позволяет Spring вызывать различные ограничения проверки.
Рабочий пример
зависимость от gradle
compile 'org.springframework.boot:spring-boot-starter'
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-validation'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile("mysql:mysql-connector-java:8.0.16")
UserRepository.java
@Validated
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findUserByName(@NotEmpty String name);
}
Вывод на консоль
javax.validation.ConstraintViolationException: findUserByName.name: must not be empty
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:117) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy88.findUserByName(Unknown Source) ~[na:na]
at com.test.validation.controller.UserController.get(UserController.java:18) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
Комментарии:
1. @User0123 есть ли у вас зависимость spring-boot-starter-validation?
2. @User0123 Это сработало для меня. Есть ли у вас следующая зависимость? mvnrepository.com/artifact/javax.validation/validation-api /. …
Ответ №2:
репозитории не имеют возможности получить к нему прямой доступ из классов сервисов, поэтому вам нужно создать класс сервиса с аннотацией @Service, затем реализовать свой собственный метод для поиска пользователя с помощью интерфейса репозитория UserRepo, затем вы можете внедрить класс service в модуль тестирования и выполнить свои собственные тесты.
Комментарии:
1. Я не думаю, что вы понимаете мой вопрос, чтобы было ясно, что я хочу: если я вызываю findUserByEmail(null) Я хочу, чтобы метод репозитория вызывал исключение IllegalArgumentException
2. вы не можете вызвать исключение IllegalArgumentException непосредственно из репозитория, подробнее о DataAccessException: docs.spring.io/spring-framework/docs/current/javadoc-api/org /…
3. Итак, нет лучшего способа проверить, что параметр не является пустым, если не указано выше? С уровня обслуживания с использованием Assert?
4. в качестве параметра вы можете использовать аннотацию @NotNull, чтобы убедиться, что переданный параметр, аннотированный им, не будет иметь значения null в такой ситуации
5. добавьте этот фрагмент перед возвращением инструкции » if (email == null) { throw new IllegalArgumentException(«Такое электронное письмо не найдено «); } »