First, add the Hibernate Validator configuration to your application:
<groupId>io.micronaut.beanvalidation</groupId>
<artifactId>micronaut-hibernate-validator</artifactId>
</dependency>
We can validate parameters using javax.validation
annotations and the annotation at the class level.
Example
import io.micronaut.context.annotation.Requires;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.validation.Validated;
import javax.validation.constraints.NotBlank;
import java.util.Collections;
@Validated (1)
@Controller("/email")
public class EmailController {
@Get("/send")
public HttpResponse send(@NotBlank String recipient, (2)
@NotBlank String subject) { (2)
return HttpResponse.ok(Collections.singletonMap("msg", "OK"));
}
}
Example
import io.micronaut.context.annotation.Requires;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.validation.Validated;
import javax.validation.constraints.NotBlank;
import java.util.Collections;
@Validated (1)
@Controller("/email")
class EmailController {
@Get("/send")
HttpResponse send(@NotBlank String recipient, (2)
@NotBlank String subject) { (2)
HttpResponse.ok(Collections.singletonMap("msg", "OK"))
}
}
import io.micronaut.context.annotation.Requires
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.validation.Validated
import javax.validation.constraints.NotBlank
import java.util.Collections
@Validated (1)
@Controller("/email")
open class EmailController {
@Get("/send")
open fun send(@NotBlank recipient: String, (2)
@NotBlank subject: String): HttpResponse<*> { (2)
return HttpResponse.ok(Collections.singletonMap("msg", "OK"))
}
}
If a validation error occurs a javax.validation.ConstraintViolationException
will be thrown. By default, the integrated io.micronaut.validation.exception.ConstraintExceptionHandler
is used to handle the exception leading to a behaviour as shown in the following test:
Example Test
Example Test
def "test parameter validation"() {
when:
client.toBlocking().exchange('/email/send?subject=Hi&recipient=')
then:
def e = thrown(HttpClientResponseException)
def response = e.response
response.status == HttpStatus.BAD_REQUEST
when:
response = client.toBlocking().exchange('/email/send?subject=Hi&recipient=me@micronaut.example')
then:
response.status == HttpStatus.OK
}
Example Test
"test params are validated"() {
val e = shouldThrow<HttpClientResponseException> {
client.toBlocking().exchange<Any>("/email/send?subject=Hi&recipient=")
}
var response = e.response
response.status shouldBe HttpStatus.BAD_REQUEST
response.status shouldBe HttpStatus.OK
}
Often, you may want to use POJOs as controller method parameters.
/*
* Copyright 2017-2020 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.docs.datavalidation.pogo;
import io.micronaut.core.annotation.Introspected;
import javax.validation.constraints.NotBlank;
@Introspected
public class Email {
@NotBlank (1)
String subject;
@NotBlank (1)
String recipient;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
}
/*
* Copyright 2017-2020 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.docs.datavalidation.pogo;
import io.micronaut.core.annotation.Introspected;
import javax.validation.constraints.NotBlank;
@Introspected
class Email {
@NotBlank (1)
String subject;
@NotBlank (1)
String recipient;
}
You need to annotate your controller with Validated. Also, you need to annotate the binding POJO with @Valid
.
Example
import io.micronaut.context.annotation.Requires;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.validation.Validated;
import javax.validation.Valid;
import java.util.Collections;
@Validated (1)
@Controller("/email")
public class EmailController {
@Post("/send")
public HttpResponse send(@Body @Valid Email email) { (2)
return HttpResponse.ok(Collections.singletonMap("msg", "OK")); }
}
Example
import io.micronaut.context.annotation.Requires;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import io.micronaut.validation.Validated;
import javax.validation.Valid;
import java.util.Collections;
@Validated (1)
@Controller("/email")
class EmailController {
@Post("/send")
HttpResponse send(@Body @Valid Email email) { (2)
HttpResponse.ok(Collections.singletonMap("msg", "OK"))
}
}
import io.micronaut.context.annotation.Requires
import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.micronaut.validation.Validated
import javax.validation.Valid
import java.util.Collections
@Validated (1)
@Controller("/email")
open class EmailController {
@Post("/send")
open fun send(@Body @Valid email: Email): HttpResponse<*> { (2)
return HttpResponse.ok(Collections.singletonMap("msg", "OK"))
}
}
The validation of POJOs is shown in the following test:
public void testPoJoValidation() {
HttpClientResponseException e = Assertions.assertThrows(HttpClientResponseException.class, () -> {
Email email = new Email();
email.subject = "Hi";
email.recipient = "";
client.toBlocking().exchange(HttpRequest.POST("/email/send", email));
});
HttpResponse response = e.getResponse();
assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
Email email = new Email();
email.subject = "Hi";
email.recipient = "me@micronaut.example";
response = client.toBlocking().exchange(HttpRequest.POST("/email/send", email));
assertEquals(HttpStatus.OK, response.getStatus());
}
"test poko validation"() {
val e = shouldThrow<HttpClientResponseException> {
val email = Email()
email.subject = "Hi"
email.recipient = ""
client.toBlocking().exchange<Email, Any>(HttpRequest.POST("/email/send", email))
}
var response = e.response
response.status shouldBe HttpStatus.BAD_REQUEST
val email = Email()
email.subject = "Hi"
email.recipient = "me@micronaut.example"
response = client.toBlocking().exchange<Email, Any>(HttpRequest.POST("/email/send", email))
response.status shouldBe HttpStatus.OK