日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java jax-rs_在Java EE 6中将Bean验证与JAX-RS集成

發布時間:2023/12/3 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java jax-rs_在Java EE 6中将Bean验证与JAX-RS集成 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java jax-rs

JavaBeans驗證(Bean驗證)是Java EE 6平臺的一部分提供的新驗證模型。 約束通過以JavaBeans組件(例如托管Bean)的字段,方法或類上的注釋形式的約束來支持Bean驗證模型。

javax.validation.constraints包中提供了幾個內置約束。 Java EE 6教程列出了所有內置約束。

Bean驗證中的約束通過Java注釋表示:

public class Person {@NotNull@Size(min = 2, max = 50)private String name;// ... }

Bean驗證和RESTful Web服務

JAX-RS 1.0為提取請求值并將其綁定到Java字段,屬性和參數(使用@HeaderParam , @QueryParam等注釋)提供了強大的支持。它還支持通過非注釋參數將請求實體主體綁定到Java對象中(也就是說,未使用任何JAX-RS注釋進行注釋的參數)。 當前,必須以編程方式對資源類中的這些值進行任何其他驗證。

下一個發行版JAX-RS 2.0包含一項建議,以使驗證批注可以與JAX-RS批注結合使用。 例如,給定驗證批注@Pattern ,以下示例顯示如何驗證表單參數。

@GET @Path('{id}') public Person getPerson(@PathParam('id')@Pattern(regexp = '[0-9]+', message = 'The id must be a valid number')String id) {return persons.get(id); }

但是,目前,唯一的解決方案是使用專有實現。 接下來介紹的是基于JBoss的RESTEasy框架的解決方案,該解決方案符合JAX-RS規范,并通過注釋@ValidateRequest添加了RESTful驗證接口。

導出的接口允許我們創建自己的實現。 但是,已經有一種廣泛使用的方法,RESTEasy還向其提供了無縫集成。 這個實現是Hibernate Validator 。 可以通過以下Maven依賴項將此提供程序添加到項目中:

<dependency><groupId>org.jboss.resteasy</groupId><artifactId>resteasy-jaxrs</artifactId><version>2.3.2.Final</version><scope>provided</scope> </dependency> <dependency><groupId>org.jboss.resteasy</groupId><artifactId>resteasy-hibernatevalidator-provider</artifactId><version>2.3.2.Final</version> </dependency>

注意:在類或方法級別不聲明@ValidateRequest , @ValidateRequest在方法上應用了約束注釋,也不會進行驗證,例如上面的示例。

@GET @Path('{id}') @ValidateRequest public Person getPerson(@PathParam('id')@Pattern(regexp = '[0-9]+', message = 'The id must be a valid number')String id) {return persons.get(id); }

應用注釋后,發出請求時將自動驗證參數id 。
您當然可以通過使用注釋@Valid驗證整個實體,而不是單個字段。 例如,我們可以有一個接受Person對象并對其進行驗證的方法。

@POST @Path('/validate') @ValidateRequest public Response validate(@Valid Person person) {// ... }

注意:

默認情況下,當驗證失敗時,容器將引發異常,并將HTTP 500狀態返回給客戶端。 可以/應該重寫此默認行為,使我們能夠自定義通過異常映射器返回給客戶端的Response。

國際化

到目前為止,我們一直在使用默認的或硬編碼的錯誤消息,但這既是一種不好的做法,又一點也不靈活。 I18n是Bean驗證規范的一部分,它使我們能夠使用資源屬性文件來指定自定義錯誤消息。 默認資源文件名稱為ValidationMessages.properties并且必須包含屬性/值對,例如:

person.id.pattern=The person id must be a valid number person.name.size=The person name must be between {min} and {max} chars long

注意:

{min} , {max}是指與消息相關聯的約束的屬性。

然后可以將這些已定義的消息注入驗證約束中,如下所示:

@POST @Path('create') @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response createPerson(@FormParam('id')@Pattern(regexp = '[0-9]+', message = '{person.id.pattern}')String id,@FormParam('name')@Size(min = 2, max = 50, message = '{person.name.size}')String name) {Person person = new Person();person.setId(Integer.valueOf(id));person.setName(name);persons.put(Integer.valueOf(id), person);return Response.status(Response.Status.CREATED).entity(person).build(); }

要提供其他語言的翻譯,必須使用翻譯后的消息創建一個新的ValidationMessages_XX.properties文件,其中XX是所提供語言的代碼。

不幸的是,Hibernate Validator提供程序不基于特定的HTTP請求支持i18n。 它不考慮Accept-Language HTTP標頭,并且始終使用Locale.getDefault()提供的默認Locale 。 為了能夠改變Locale使用Accept-Language HTTP標頭(例如,改變語言在瀏覽器選項),必須提供自定義實現。

定制驗證器提供者

以下代碼旨在解決此問題,并已通過JBoss AS 7.1進行了測試。

首先要做的是刪除Maven resteasy-hibernatevalidator-provider依賴性,因為我們提供了自己的提供程序,并添加了Hibernate Validator依賴性:

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>4.2.0.Final</version> </dependency>

接下來,創建一個自定義消息插值器以調整使用的默認Locale 。

public class LocaleAwareMessageInterpolator extendsResourceBundleMessageInterpolator {private Locale defaultLocale = Locale.getDefault();public void setDefaultLocale(Locale defaultLocale) {this.defaultLocale = defaultLocale;}@Overridepublic String interpolate(final String messageTemplate,final Context context) {return interpolate(messageTemplate, context, defaultLocale);}@Overridepublic String interpolate(final String messageTemplate,final Context context, final Locale locale) {return super.interpolate(messageTemplate, context, locale);} }

下一步是提供ValidatorAdapter 。 引入此接口是為了將RESTEasy與實際的驗證API分離。

public class RESTValidatorAdapter implements ValidatorAdapter {private final Validator validator;private final MethodValidator methodValidator;private final LocaleAwareMessageInterpolator interpolator = new LocaleAwareMessageInterpolator();public RESTValidatorAdapter() {Configuration<?> configuration = Validation.byDefaultProvider().configure();this.validator = configuration.messageInterpolator(interpolator).buildValidatorFactory().getValidator();this.methodValidator = validator.unwrap(MethodValidator.class);}@Overridepublic void applyValidation(Object resource, Method invokedMethod,Object[] args) {// For the i8n to work, the first parameter of the method being validated must be a HttpHeadersif ((args != null) && (args[0] instanceof HttpHeaders)) {HttpHeaders headers = (HttpHeaders) args[0];List<Locale> acceptedLanguages = headers.getAcceptableLanguages();if ((acceptedLanguages != null) && (!acceptedLanguages.isEmpty())) {interpolator.setDefaultLocale(acceptedLanguages.get(0));}}ValidateRequest resourceValidateRequest = FindAnnotation.findAnnotation(invokedMethod.getDeclaringClass().getAnnotations(), ValidateRequest.class);if (resourceValidateRequest != null) {Set<ConstraintViolation<?>> constraintViolations = new HashSet<ConstraintViolation<?>>(validator.validate(resource,resourceValidateRequest.groups()));if (constraintViolations.size() > 0) {throw new ConstraintViolationException(constraintViolations);}}ValidateRequest methodValidateRequest = FindAnnotation.findAnnotation(invokedMethod.getAnnotations(), ValidateRequest.class);DoNotValidateRequest doNotValidateRequest = FindAnnotation.findAnnotation(invokedMethod.getAnnotations(),DoNotValidateRequest.class);if ((resourceValidateRequest != null || methodValidateRequest != null)&& doNotValidateRequest == null) {Set<Class<?>> set = new HashSet<Class<?>>();if (resourceValidateRequest != null) {for (Class<?> group : resourceValidateRequest.groups()) {set.add(group);}}if (methodValidateRequest != null) {for (Class<?> group : methodValidateRequest.groups()) {set.add(group);}}Set<MethodConstraintViolation<?>> constraintViolations = new HashSet<MethodConstraintViolation<?>>(methodValidator.validateAllParameters(resource,invokedMethod, args,set.toArray(new Class<?>[set.size()])));if (constraintViolations.size() > 0) {throw new MethodConstraintViolationException(constraintViolations);}}} }

警告:

需要將@HttpHeaders作為要驗證的方法的第一個參數注入:

@POST @Path('create') @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response createPerson(@Context HttpHeaders headers,@FormParam('id')@Pattern(regexp = '[0-9]+', message = '{person.id.pattern}')String id,@FormParam('name')@Size(min = 2, max = 50, message = '{person.name.size}')String name) {Person person = new Person();person.setId(Integer.valueOf(id));person.setName(name);persons.put(id, person);return Response.status(Response.Status.CREATED).entity(person).build(); }

最后,創建將選擇以上用于驗證Bean驗證約束的類的提供程序:

@Provider public class RESTValidatorContextResolver implementsContextResolver<ValidatorAdapter> {private static final RESTValidatorAdapter adapter = new RESTValidatorAdapter();@Overridepublic ValidatorAdapter getContext(Class<?> type) {return adapter;} }

映射異常

Bean驗證API使用類型為javax.validation.ValidationException或其任何子類的異常報告錯誤情況。 應用程序可以為任何異常提供自定義異常映射提供程序。 JAX-RS實現必須始終使用其泛型類型是異常的最接近超類的提供程序,其中應用程序定義的提供程序優先于內置提供程序。

異常映射器可能看起來像:

@Provider public class ValidationExceptionMapper implementsExceptionMapper<MethodConstraintViolationException> {@Overridepublic Response toResponse(MethodConstraintViolationException ex) {Map<String, String> errors = new HashMap<String, String>();for (MethodConstraintViolation<?> methodConstraintViolation : ex.getConstraintViolations()) {errors.put(methodConstraintViolation.getParameterName(),methodConstraintViolation.getMessage());}return Response.status(Status.PRECONDITION_FAILED).entity(errors).build();} }

上面的示例顯示了ExceptionMapper的實現,該映射映射了MethodConstraintViolationException類型的MethodConstraintViolationException 。 當用@ValidateRequest注釋的方法的一個或多個參數的驗證失敗時,Hibernate Validator實現將引發此異常。 這樣可以確保客戶端收到格式化的響應,而不僅僅是從資源傳播的異常。

源代碼

這篇文章使用的源代碼可以在GitHub上找到 。

警告:

重命名資源屬性文件,以使文件ValidationMessages.properties (即,沒有任何后綴)可以映射到Locale.getDefault()返回的Locale 。

相關文章

  • Java和UTF-8編碼
  • 作為JBoss AS 7模塊運行Drools 5.4.0 Final
  • 比較設備描述存儲庫
  • Java EE 6測試第二部分– Arquillian和ShrinkWrap簡介
  • Java EE 6測試第I部分– EJB 3.1可嵌入API
  • 上一篇文章:作為JBoss AS 7模塊運行Drools 5.4.0 Final

參考:來自Samaxes博客的JCG合作伙伴 Samuel Santos的Java EE 6中的Bean驗證與JAX-RS集成 。

翻譯自: https://www.javacodegeeks.com/2013/01/integrating-bean-validation-with-jax-rs-in-java-ee-6.html

java jax-rs

總結

以上是生活随笔為你收集整理的java jax-rs_在Java EE 6中将Bean验证与JAX-RS集成的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。