Interpolação de mensagem de validação de mola
1. Introdução
A interpolação de mensagens é o processo usado para criar mensagens de erro para restriçõesJava bean validation. Por exemplo, podemos ver as mensagens fornecendo um valornull para um campo anotado com a anotaçãojavax.validation.constraints.NotNull.
Neste tutorial, aprenderemos como usar a interpolação de mensagem padrão do Spring e como criar nosso próprio mecanismo de interpolação.
Para ver exemplos de outras bibliotecas que fornecem restrições além dejavax.validation, dê uma olhada emHibernate Validator Specific Constraints. Também podemos criar umcustom Spring Validation annotation.
2. Interpolação de mensagem padrão
Antes de entrar em snippets de código, vamos considerar um exemplo de uma resposta HTTP 400 com uma mensagem de violação de restrição@NotNull padrão:
{
....
"status": 400,
"error": "Bad Request",
"errors": [
{
....
"defaultMessage": "must not be null",
....
}
],
"message": "Validation failed for object='notNullRequest'. Error count: 1",
....
}
Spring retrieves the constraint violation message details from message descriptors. Cada restrição define seu descritor de mensagem padrão usando o atributomessage. Mas, é claro, podemos substituí-lo por um valor personalizado.
Como exemplo, criaremos um controlador REST simples com um método POST:
@RestController
public class RestExample {
@PostMapping("/test-not-null")
public void testNotNull(@Valid @RequestBody NotNullRequest request) {
// ...
}
}
O corpo da solicitação será mapeado para o objetoNotNullRequest, que tem apenas um arquivoString anotado com@NotNull:
public class NotNullRequest {
@NotNull(message = "stringValue has to be present")
private String stringValue;
// getters, setters
}
Agora, quando enviarmos uma solicitação POST que falhe nessa verificação de validação, veremos nossa mensagem de erro personalizada:
{
...
"errors": [
{
...
"defaultMessage": "stringValue has to be present",
...
}
],
...
}
O único valor que muda édefaultMessage. Mas ainda temos muitas informações sobre códigos de erro, nome do objeto, nome do campo etc. Para limitar o número de valores exibidos, podemos implementarCustom Error Message Handling for REST API.
3. Interpolação com expressões de mensagem
Na primavera, podemosuse the Unified Expression Language to define our message descriptors. Isso permite definirerror messages based on conditional logic and also enables advanced formatting options.
Para entender mais claramente, vejamos alguns exemplos.
Em cada anotação de restrição, podemos acessar o valor real de um campo que está sendo validado:
@Size(
min = 5,
max = 14,
message = "The author email '${validatedValue}' must be between {min} and {max} characters long"
)
private String authorEmail;
Nossa mensagem de erro conterá o valor real da propriedade e os parâmetrosminemax da anotação@Size:
"defaultMessage": "The author email '[email protected]' must be between 5 and 14 characters long"
Observe que para acessar variáveis externas, usamos a sintaxe$\{}, mas para acessar outras propriedades da anotação de validação, usamos\{}.
Também é possível usar o operador ternário:
@Min(
value = 1,
message = "There must be at least {value} test{value > 1 ? 's' : ''} in the test case"
)
private int testCount;
O Spring converterá o operador ternário em um único valor na mensagem de erro:
"defaultMessage": "There must be at least 2 tests in the test case"
Também podemos chamar métodos em variáveis externas:
@DecimalMin(
value = "50",
message = "The code coverage ${formatter.format('%1$.2f', validatedValue)} must be higher than {value}%"
)
private double codeCoverage;
Entrada inválida produzirá uma mensagem de erro com o valor formatado:
"defaultMessage": "The code coverage 44.44 must be higher than 50%"
Como podemos ver nesses exemplos, alguns caracteres como\{, }, $,e/ são usados em expressões de mensagem, portanto, precisamos escapá-los com um caractere de barra invertida antes de usá-los literalmente:\{, \}, \$, e \.
4. Interpolação de mensagem personalizada
Em alguns casos, queremosimplement a custom message interpolation engine. Para fazer isso, devemos primeiro implementar a interfacejavax.validation.MessageInterpolation:
public class MyMessageInterpolator implements MessageInterpolator {
private final MessageInterpolator defaultInterpolator;
public MyMessageInterpolator(MessageInterpolator interpolator) {
this.defaultInterpolator = interpolator;
}
@Override
public String interpolate(String messageTemplate, Context context) {
messageTemplate = messageTemplate.toUpperCase();
return defaultInterpolator.interpolate(messageTemplate, context);
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
messageTemplate = messageTemplate.toUpperCase();
return defaultInterpolator.interpolate(messageTemplate, context, locale);
}
}
Nesta implementação simples, estamos apenas alterando a mensagem de erro para maiúsculas. Ao fazer isso, nossa mensagem de erro será semelhante a:
"defaultMessage": "THE CODE COVERAGE 44.44 MUST BE HIGHER THAN 50%"
Também precisamosregister our interpolator na fábricajavax.validation.Validation:
Validation.byDefaultProvider().configure().messageInterpolator(
new MyMessageInterpolator(
Validation.byDefaultProvider().configure().getDefaultMessageInterpolator())
);
5. Conclusão
Neste artigo, aprendemos como funciona a interpolação de mensagens padrão do Spring e como criar um mecanismo de interpolação de mensagens personalizado.
E, como sempre, todo o código-fonte está disponívelover on GitHub.