A API de registro se torna RESTful
1. Visão geral
Nos últimos artigos dethe Registration series here on example, construímos a maioria das funcionalidades de que precisávamos em um estilo MVC.
Agora vamos fazer a transição de algumas dessas APIs para uma abordagem mais RESTful.
2. A operação deRegister
Vamos começar com a operação principal do Registro:
@RequestMapping(value = "/user/registration", method = RequestMethod.POST)
@ResponseBody
public GenericResponse registerUserAccount(
@Valid UserDto accountDto, HttpServletRequest request) {
logger.debug("Registering user account with information: {}", accountDto);
User registered = createUserAccount(accountDto);
if (registered == null) {
throw new UserAlreadyExistException();
}
String appUrl = "http://" + request.getServerName() + ":" +
request.getServerPort() + request.getContextPath();
eventPublisher.publishEvent(
new OnRegistrationCompleteEvent(registered, request.getLocale(), appUrl));
return new GenericResponse("success");
}
Então - como essa forma é diferente da implementação original focada no MVC?
Aqui vai:
-
a solicitação agora está mapeada corretamente para um HTTP POST
-
agora estamos retornando um DTO adequado e organizando-o por meio da anotação@ResponseBody diretamente no corpo da Resposta
-
não estamos mais lidando com tratamento de erros no método
Também estamos removendo o antigoshowRegistrationPage() - já que não é necessário simplesmente exibir a página de registro.
3. Oregistration.html
Com essas mudanças, agora precisamos modificar oregistration.html para:
-
use o Ajax para enviar o formulário de inscrição
-
receber os resultados da operação como JSON
Aqui vai:
form
4. Manipulação de exceção
Juntamente com a API mais RESTful, a lógica de manipulação de exceções também se tornará mais madura.
Estamos usando o mesmo mecanismo@ControllerAdvice para lidar de forma limpa com as exceções lançadas pelo aplicativo - e agora precisamos de um novo tipo de exceção.
Este é oBindException - que é lançado quandoUserDto é validado (se inválido). Iremos substituir o métodoResponseEntityExceptionHandler padrãohandleBindException() para adicionar os erros no corpo da resposta:
@Override
protected ResponseEntity
Também precisaremos lidar com nossoExceptionUserAlreadyExistException personalizado - que é acionado quando o usuário se registra com um e-mail já existente:
@ExceptionHandler({ UserAlreadyExistException.class })
public ResponseEntity
5. OGenericResponse
Também precisamos melhorar a implementação deGenericResponse para conter esses erros de validação:
public class GenericResponse {
public GenericResponse(List fieldErrors, List globalErrors) {
super();
ObjectMapper mapper = new ObjectMapper();
try {
this.message = mapper.writeValueAsString(fieldErrors);
this.error = mapper.writeValueAsString(globalErrors);
} catch (JsonProcessingException e) {
this.message = "";
this.error = "";
}
}
}
6. UI - Erros de campo e globais
Finalmente, vamos ver como lidar com erros de campo e globais usando jQuery:
var serverContext = [[function register(){
$(".alert").html("").hide();
var formData= $('form').serialize();
$.post(serverContext + "/user/registration",formData ,function(data){
if(data.message == "success"){
window.location.href = serverContext +"/successRegister.html";
}
})
.fail(function(data) {
if(data.responseJSON.error.indexOf("MailError") > -1)
{
window.location.href = serverContext + "/emailError.html";
}
else if(data.responseJSON.error.indexOf("InternalError") > -1){
window.location.href = serverContext +
"/login.html?message=" + data.responseJSON.message;
}
else if(data.responseJSON.error == "UserAlreadyExist"){
$("#emailError").show().html(data.responseJSON.message);
}
else{
var errors = $.parseJSON(data.responseJSON.message);
$.each( errors, function( index,item ){
$("#"+item.field+"Error").show().html(item.defaultMessage);
});
errors = $.parseJSON(data.responseJSON.error);
$.each( errors, function( index,item ){
$("#globalError").show().append(item.defaultMessage+"
");
});
}
}
Observe que:
-
Se houver erros de validação - então o objetomessage contém os erros de campo e o objetoerror contém erros globais
-
Exibimos cada erro de campo próximo ao seu campo
-
Exibimos todos os erros globais em um só lugar no final do formulário
7. Conclusão
O foco deste artigo rápido é levar a API a uma direção mais RESTful e mostrar uma maneira simples de lidar com essa API no front-end.
O front end do jQuery em si não é o foco - apenas um cliente potencial básico que pode ser implementado em qualquer número de estruturas JS, enquanto a API permanece exatamente a mesma.
Ofull implementation deste tutorial pode ser encontrado emthe github project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.