JAX-RSのBean Validationの例

4 min read読了の目安(約3700字

JAX-RSのBean Validationのいくつかの例を上げる。

validatorはjavax.validation.constraintsにある。例えば次のようになる。
@DecimalMax@DecimalMinは名前の通り整数値の下限・上限を定める。@Patternは正規表現で文字列のパターンを定める。


import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

// ...
// ......
// ...

@Path("/")
public class HelloValidateSampleResource {
    @GET
    @Path("minmax")
    public String minmax(
            @NotNull @DecimalMax(value = "10") @DecimalMin(value = "3") @QueryParam("number") int number) {
        return Integer.toString(number * 10);
    }

    @GET
    @Path("pattern")
    public String pattern(
            @NotNull @Pattern(regexp = "a+b*c") @QueryParam("pattern") String pattern) {
        return "pattern = " + pattern;
    }
}

実際にテストしてみる。

class HelloValidateSampleResourceTest extends Specification {
    @Shared
    def jerseyTest = new JerseyTest() {
        @Override
        protected Application configure() {
            return new ResourceConfig(HelloValidateSampleResource.class).
                    property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true)
        }
    }

    def setupSpec() {
        jerseyTest.setUp()
    }

    def cleanupSpec() {
        jerseyTest.tearDown()
    }

    def "test minmax"() {
        when:
        def response = jerseyTest.target("/minmax").queryParam("number", "5").request().get()

        then:
        response.getStatus() == 200
        response.readEntity(String.class) == "50"

        expect:
        jerseyTest.target("/minmax").request().get().getStatus() != 200
        jerseyTest.target("/minmax").queryParam("number", "20").request().get().getStatus() != 200
        jerseyTest.target("/minmax").queryParam("number", "1").request().get().getStatus() != 200
    }

    def "test pattern" () {
        expect:
        jerseyTest.target("/pattern").queryParam("pattern", "abc").request().get().getStatus() == 200
        jerseyTest.target("/pattern").queryParam("pattern", "aac").request().get().getStatus() == 200

        jerseyTest.target("/pattern").queryParam("pattern", "xxx").request().get().getStatus() != 200
        jerseyTest.target("/pattern").queryParam("pattern", "xabc").request().get().getStatus() != 200
    }
}

またorg.hibernate.validator.constraintsにもvalidatorが定義されている。その例。

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

// ...
// ......
// ...

    @GET
    @Path("length")
    public String length(@NotNull @Length(min = 3, max = 10) @QueryParam("str") String str) {
        return str;
    }

    @GET
    @Path("email")
    public String email(@NotNull @Email @QueryParam("email") String email) {
        return email;
    }
}

テストは次の通り。

    def "test length" () {
        expect:
        jerseyTest.target("/length").queryParam("str", "1234567").request().get().getStatus() == 200
        jerseyTest.target("/length").queryParam("str", "123").request().get().getStatus() == 200

        jerseyTest.target("/length").queryParam("str", "abcdefghijk").request().get().getStatus() != 200
        jerseyTest.target("/length").queryParam("str", "aa").request().get().getStatus() != 200
    }

    def "test email" () {
        expect:
        jerseyTest.target("/email").queryParam("email", "test@example.org").request().get().getStatus() == 200
        jerseyTest.target("/email").queryParam("email", "test@localhost").request().get().getStatus() == 200

        jerseyTest.target("/email").queryParam("email", "test").request().get().getStatus() != 200
    }