Estou aprendendo JAX-RS (também conhecido como JSR-311) usando Jersey. Criei com êxito um Recurso Raiz e estou brincando com os parâmetros:
@Path("/hello")
public class HelloWorldResource {
@GET
@Produces("text/html")
public String get(
@QueryParam("name") String name,
@QueryParam("birthDate") Date birthDate) {
// Return a greeting with the name and age
}
}
Isso funciona muito bem e manipula qualquer formato no código de idioma atual que seja entendido pelo construtor Date (String) (como AAAA / mm / dd e mm / dd / AAAA). Mas se eu fornecer um valor inválido ou não compreendido, recebo uma resposta 404.
Por exemplo:
GET /hello?name=Mark&birthDate=X
404 Not Found
Como posso personalizar esse comportamento? Talvez um código de resposta diferente (provavelmente "400 Request Bad")? Que tal registrar um erro? Talvez adicione uma descrição do problema ("formato de data inválido") em um cabeçalho personalizado para ajudar na solução de problemas? Ou retornar uma resposta de erro inteira com detalhes, junto com um código de status 5xx?
ExceptionMapper
interface (que é uma abordagem melhor do que a extensão). Veja mais aqui vvirlan.wordpress.com/2015/10/19/…Crie a classe acima. Isso manipulará 404 (NotFoundException) e aqui no método toResponse você poderá fornecer sua resposta personalizada. Da mesma forma, existem ParamException etc. que você precisaria mapear para fornecer respostas personalizadas.
fonte
Jersey lança um com.sun.jersey.api.ParamException quando falha ao desmarcar os parâmetros, portanto, uma solução é criar um ExceptionMapper que lida com esses tipos de exceções:
fonte
Você também pode escrever uma classe reutilizável para variáveis anotadas por QueryParam
use-o assim:
Embora o tratamento de erros seja trivial nesse caso (lançando uma resposta de 400), o uso dessa classe permite fatorar o tratamento de parâmetros em geral, que pode incluir o registro etc.
fonte
DateParam
acima, que envolve um emorg.joda.time.DateTime
vez dejava.util.Calendar
. Você usa isso@QueryParam
mais do queDateTime
ele próprio.JodaModule
que pode ser registrado com oObjectMapper
registerModules
método Ele pode lidar com todas as conversões do tipo joda.com.fasterxml.jackson.datatype.joda.JodaModule
Uma solução óbvia: pegue uma String, converta você mesmo para o Date. Dessa forma, você pode definir o formato desejado, capturar exceções e repetir ou personalizar o erro que está sendo enviado. Para análise, SimpleDateFormat deve funcionar bem.
Estou certo de que existem maneiras de conectar manipuladores para tipos de dados também, mas talvez um pouco de código simples seja tudo o que você precisa nesse caso.
fonte
Eu também gosto de StaxMan provavelmente implementaria esse QueryParam como uma String e depois lidaria com a conversão, reconvertendo conforme necessário.
Se o comportamento específico da localidade for o comportamento desejado e esperado, você usaria o seguinte para retornar o erro 400 BAD REQUEST:
throw new WebApplicationException(Response.Status.BAD_REQUEST);
Consulte o JavaDoc para javax.ws.rs.core.Response.Status para obter mais opções.
fonte
A documentação do @QueryParam diz
Se você deseja controlar qual resposta vai para o usuário quando o parâmetro de consulta no formulário String não pode ser convertido para o seu tipo T, você pode lançar WebApplicationException. O Dropwizard vem com as seguintes classes * Param que você pode usar para suas necessidades.
BooleanParam, DateTimeParam, IntParam, LongParam, LocalDateParam, NonEmptyStringParam, UUIDParam. Vejo https://github.com/dropwizard/dropwizard/tree/master/dropwizard-jersey/src/main/java/io/dropwizard/jersey/params
Se você precisar do Joda DateTime, use o Dropwizard DateTimeParam .
Se a lista acima não atender às suas necessidades, defina sua própria extensão estendendo AbstractParam. Substituir método de análise. Se você precisar de controle sobre o corpo da resposta a erros, substitua o método de erro.
Bom artigo de Coda Hale sobre isso está em http://codahale.com/what-makes-jersey-interesting-parameter-classes/
O construtor Date (String arg) foi descontinuado. Eu usaria as classes de data do Java 8 se você estivesse no Java 8. Caso contrário, o joda date time é recomendado.
fonte
Este é o comportamento correto, na verdade. Jersey tentará encontrar um manipulador para sua entrada e tentará construir um objeto a partir da entrada fornecida. Nesse caso, ele tentará criar um novo objeto Date com o valor X fornecido ao construtor. Como essa é uma data inválida, por convenção, Jersey retornará 404.
O que você pode fazer é reescrever e colocar a data de nascimento como uma String e, em seguida, tentar analisar e, se você não conseguir o que deseja, poderá liberar qualquer exceção que desejar por qualquer mecanismo de mapeamento de exceção (existem vários )
fonte
Eu estava enfrentando o mesmo problema.
Eu queria pegar todos os erros em um local central e transformá-los.
A seguir, está o código de como eu lidei com isso.
Crie a seguinte classe que implementa
ExceptionMapper
e adicione@Provider
anotações nessa classe. Isso irá lidar com todas as exceções.Substitua o
toResponse
método e retorne o objeto Response preenchido com dados customizados.fonte
Abordagem 1: estendendo a classe WebApplicationException
Crie uma nova exceção estendendo WebApplicationException
Agora lance 'RestException' sempre que necessário.
Você pode ver a inscrição completa neste link .
Abordagem 2: Implementar ExceptionMapper
O mapeador a seguir lida com exceção do tipo 'DataNotFoundException'
Você pode ver a inscrição completa neste link .
fonte
Apenas como uma extensão para a resposta de Steven Lavine, caso você queira abrir a janela de login do navegador. Achei difícil retornar corretamente a resposta ( autenticação HTTP MDN ) do filtro, caso o usuário ainda não estivesse autenticado
Isso me ajudou a criar a resposta para forçar o login do navegador, observe as modificações adicionais dos cabeçalhos. Isso definirá o código de status como 401 e definirá o cabeçalho que faz com que o navegador abra a caixa de diálogo nome de usuário / senha.
fonte