Negociação de conteúdo do Spring MVC
1. Visão geral
Este artigo descreve como implementar a negociação de conteúdo em um projeto Spring MVC.
Geralmente, existem três opções para determinar o tipo de mídia de uma solicitação:
-
Usando sufixos de URL (extensões) na solicitação (por exemplo,.xml/.json)
-
Usando o parâmetro de URL na solicitação (por exemplo,?format=json)
-
Usando o cabeçalhoAccept na solicitação
Por padrão, essa é a ordem na qual o gerenciador de negociação de conteúdo do Spring tentará usar essas três estratégias. E se nada disso estiver ativado, podemos especificar um fallback para um tipo de conteúdo padrão.
2. Estratégias de negociação de conteúdo
Vamos começar com as dependências necessárias - estamos trabalhando com representações JSON e XML, portanto, para este artigo, usaremos Jackson para JSON:
com.fasterxml.jackson.core
jackson-core
2.7.2
com.fasterxml.jackson.core
jackson-databind
2.7.2
Para suporte XML, podemos usar JAXB, XStream ou o suporte Jackson-XML mais recente.
Como explicamos o uso do cabeçalhoAccept eman earlier article onHttpMessageConverters,, vamos nos concentrar nas duas primeiras estratégias em profundidade.
3. A estratégia de sufixo de URL
Por padrão, essa estratégia está desativada, mas a estrutura pode procurar uma extensão de caminho diretamente da URL para determinar o tipo de conteúdo de saída.
Antes de entrar nas configurações, vamos dar uma olhada rápida em um exemplo. Temos a seguinte implementação simples do método API em um controlador Spring típico:
@RequestMapping(
value = "/employee/{id}",
produces = { "application/json", "application/xml" },
method = RequestMethod.GET)
public @ResponseBody Employee getEmployeeById(@PathVariable long id) {
return employeeMap.get(id);
}
Vamos invocá-lo usando a extensão JSON para especificar o tipo de mídia do recurso:
curl http://localhost:8080/spring-mvc-basics/employee/10.json
Aqui está o que podemos obter de volta se usarmos uma extensão JSON:
{
"id": 10,
"name": "Test Employee",
"contactNumber": "999-999-9999"
}
E esta é a aparência da solicitação - resposta com XML:
curl http://localhost:8080/spring-mvc-basics/employee/10.xml
O corpo da resposta:
999-999-9999
10
Test Employee
Now:
Agoraif we do not use any extension ou use um que não esteja configurado - o tipo de conteúdo padrão será retornado:
curl http://localhost:8080/spring-mvc-basics/employee/10
Vamos agora dar uma olhada na configuração dessa estratégia - tanto com configurações Java quanto XML.
3.1. Configuração Java
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(false).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON);
}
Vamos repassar os detalhes.
Primeiro, estamos ativando a estratégia de extensões de caminho.
Então, estamos desativando a estratégia de parâmetro de URL, bem como a estratégia de cabeçalhoAccept - porque queremos contar apenas com a extensão do caminho para determinar o tipo de conteúdo.
Então, estamos desativando o Java Activation Framework; JAF pode ser usado como um mecanismo de fallback para selecionar o formato de saída se a solicitação de entrada não corresponder a nenhuma das estratégias que configuramos. Vamos desativá-lo porque vamos configurar JSON como o tipo de conteúdo padrão.
E finalmente - estamos configurando o JSON como o padrão. Isso significa que, se nenhuma das duas estratégias for correspondida, todas as solicitações recebidas serão mapeadas para um método de controlador que atende JSON.
3.2. Configuração XML
Vamos também dar uma olhada rápida na mesma configuração exata, usando apenas XML:
4. A estratégia de parâmetro de URL
Nós usamos extensões de caminho na seção anterior - vamos agora configurar o Spring MVC para fazer uso de um parâmetro de caminho.
Podemos ativar essa estratégia definindo o valor da propriedadefavorParameter como true.
Vamos dar uma olhada rápida em como isso funcionaria com nosso exemplo anterior:
curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=json
E aqui está o que o corpo de resposta JSON será:
{
"id": 10,
"name": "Test Employee",
"contactNumber": "999-999-9999"
}
Se usarmos o parâmetro XML, a saída será no formato XML:
curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=xml
O corpo da resposta:
999-999-9999
10
Test Employee
Agora vamos fazer a configuração - novamente, primeiro usando Java e depois XML.
4.1. Configuração Java
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
Vamos ler esta configuração.
Primeiro, é claro que a extensão do caminho e as estratégias de cabeçalhoAccept estão desabilitadas (assim como JAF).
O restante da configuração é o mesmo.
4.2. Configuração XML
Além disso, podemos terboth strategies (extension and parameter) enabled ao mesmo tempo:
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
Nesse caso, o Spring procurará primeiro a extensão do caminho, se isso não estiver presente, procurará o parâmetro do caminho. E se ambos não estiverem disponíveis na solicitação de entrada, o tipo de conteúdo padrão será retornado.
5. A estratégia de cabeçalhoAccept
Se o cabeçalhoAccept estiver habilitado, Spring MVC procurará seu valor na solicitação de entrada para determinar o tipo de representação.
Temos que definir o valor deignoreAcceptHeader como falso para habilitar essa abordagem e estamos desabilitando as outras duas estratégias apenas para saber que estamos contando apenas com o cabeçalhoAccept
5.1. Configuração Java
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true).
favorParameter(false).
parameterName("mediaType").
ignoreAcceptHeader(false).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
5.2. Configuração XML
Finalmente, precisamos ativar o gerenciador de negociação de conteúdo, conectando-o à configuração geral:
6. Conclusão
E nós terminamos. Examinamos como a negociação de conteúdo funciona no Spring MVC e nos concentramos em alguns exemplos de configuração que usam várias estratégias para determinar o tipo de conteúdo.
A implementação completa deste artigo pode ser encontrada emthe github project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.