Springboot統合JSR 303の迅速な失敗と国際化

54849 ワード

目次

  • バージョン説明
  • で解決した問題
  • コードインスタンス
  • pom.xml
  • 検証エンティティクラス
  • restインタフェース
  • テストインタフェース
  • コアコード
  • 国際化クラス
  • 構成クラス
  • テスト1
  • テスト2
  • 備考
  • バージョンの説明


    springboot 2.2.6.RELEASE hibernate-validator 6.0.18.Final(springbootバージョン対応)

    どんな問題を解決しましたか。

    org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
    {"status":10001,"desc":"must be less than or equal to 2","data":null}
    
  • hibernate-validatorデフォルトfast-fail=false、つまりすべてのプロパティ
  • が検証されます.
  • hibernate-validatorデフォルト読み出しValidationMessages.propertiesプロファイル、すなわち失敗プロンプトmessageが英語
  • 本文は実現する
  • hibernate-validatorはfast-fail=trueを使用します.つまり、属性検証に失敗した場合、
  • の検証を続行しません.
  • hibernate-validatorは、デフォルトの構成言語と要求パラメータに基づいて、どのValidationMessages_*を読み込むかを決定する.propertiesプロファイル
  • コードインスタンス


    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.2.6.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.example</groupId>
    	<artifactId>demo1</artifactId>
    	<version>1.0.0-SNAPSHOT</version>
    	<name>demo1</name>
    	<description>Demo project for Spring Boot</description>
    
    	<properties>
    		<java.version>1.8</java.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-thymeleaf</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-validation</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-devtools</artifactId>
    			<scope>runtime</scope>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-configuration-processor</artifactId>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    			<exclusions>
    				<exclusion>
    					<groupId>org.junit.vintage</groupId>
    					<artifactId>junit-vintage-engine</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    
    

    エンティティクラスの検証

    package com.example.demo.rest.vo;
    
    import javax.validation.constraints.DecimalMax;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotBlank;
    
    public class UserVO {
    
    	@Min(value = 6)
    	private Integer id;
    	
    	@NotBlank
    	private String username;
    	
    	@DecimalMax(value = "2")
    	private String password;
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    }
    
    

    restインタフェース

    package com.example.demo.rest.ctrl;
    
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.example.demo.rest.vo.UserVO;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
    	
    	@PostMapping("/createUser")
    	public void createUser(@Validated UserVO userVO) {
    		System.out.println(userVO);
    	}
    }
    
    

    テストインタフェース

    package com.example.demo;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import java.nio.charset.Charset;
    
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.springframework.web.context.WebApplicationContext;
    
    @SpringBootTest
    class Demo1ApplicationTests {
    	
    	@Autowired
    	private WebApplicationContext wac;
    	
    	private MockMvc mvc;
    	
    	@BeforeEach
    	public void setup() {
    		mvc = MockMvcBuilders.webAppContextSetup(wac).build();
    	}
    
    	@Test
    	public void test() throws Exception {
    		String result = mvc.perform(post("/user/createUser")
    				.param("password", "3")
    	//			.param("l", "fr"))
    				.andExpect(status().isOk())
    				.andReturn().getResponse().getContentAsString(Charset.forName("UTF-8"));
    		System.out.println(result);
    	}
    
    }
    

    コアコード


    国際クラス

    package com.example.demo.rest.advice;
    
    import java.util.Locale;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.util.StringUtils;
    import org.springframework.web.servlet.LocaleResolver;
    
    public class MyLocaleResolver implements LocaleResolver {
    
    	@Override
    	public Locale resolveLocale(HttpServletRequest request) {
    		// , session cookie
    		String l = request.getParameter("l");
    		Locale locale = null;
    		if (StringUtils.isEmpty(l)) {
    			locale = Locale.getDefault();
    		} else {
    			String[] split = l.split("_");
    			if (split.length == 1) {
    				locale = new Locale(split[0]);
    			} else {
    				locale = new Locale(split[0], split[1]);
    			}
    		}
    		return locale;
    	}
    
    	@Override
    	public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
    		
    	}
    
    }
    

    クラスの構成

    package com.example.demo.rest.config;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
    import org.springframework.web.servlet.LocaleResolver;
    
    import com.example.demo.rest.advice.MyLocaleResolver;
    
    @Configuration
    @ConfigurationProperties(prefix = "spring.validator")
    public class ValidatorConfig {
    
    	private String failFast = "true";
    	
    	public String getFailFast() {
    		return failFast;
    	}
    
    	public void setFailFast(String failFast) {
    		this.failFast = failFast;
    	}
    	
    	@Bean
    	public LocalValidatorFactoryBean validator() {
    		LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
    		factoryBean.getValidationPropertyMap().put("hibernate.validator.fail_fast", failFast);
    		return factoryBean;
    	}
    	
    	@Bean
    	public LocaleResolver localeResolver() {
    		return new MyLocaleResolver();
    	}
    }
    
    

    テスト1

    	@Test
    	public void test() throws Exception {
    		String result = mvc.perform(post("/user/createUser")
    				.param("password", "3")
    				.param("l", "fr")) // 
    				.andExpect(status().isOk())
    				.andReturn().getResponse().getContentAsString(Charset.forName("UTF-8"));
    		System.out.println(result);
    	}
    

    結果
    org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
    {"status":10001,"desc":"ne peut pas être vide","data":null}
    

    テスト2

    	@Test
    	public void test() throws Exception {
    		String result = mvc.perform(post("/user/createUser")
    				.param("password", "3")
    				.andExpect(status().isOk())
    				.andReturn().getResponse().getContentAsString(Charset.forName("UTF-8"));
    		System.out.println(result);
    	}
    

    結果
    org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
    {"status":10001,"desc":" ","data":null}
    

    コメント


    この文書ではspringbootを使用して統一データフォーマットを返します.