Eu tenho um controlador que fornece acesso RESTful às informações:
@RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
HttpServletResponse response) {
O problema que estou enfrentando é que, se eu atingir o servidor com uma variável de caminho com caracteres especiais, ela será truncada. Por exemplo: http: // localhost: 8080 / blah-server / blah / get / blah2010.08.19-02: 25: 47
O parâmetro blahName será blah2010.08
No entanto, a chamada para request.getRequestURI () contém todas as informações passadas.
Alguma idéia de como impedir que o Spring trunque o @PathVariable?
Respostas:
Tente uma expressão regular para o
@RequestMapping
argumento:fonte
Provavelmente, isso está intimamente relacionado ao SPR-6164 . Resumidamente, a estrutura tenta aplicar alguns conhecimentos à interpretação de URI, removendo o que considera extensões de arquivo. Isso teria o efeito de se transformar
blah2010.08.19-02:25:47
emblah2010.08
, uma vez que pensa que.19-02:25:47
é uma extensão de arquivo.Conforme descrito no problema vinculado, você pode desativar esse comportamento declarando seu próprio
DefaultAnnotationHandlerMapping
bean no contexto do aplicativo e configurando suauseDefaultSuffixPattern
propriedade parafalse
. Isso substituirá o comportamento padrão e o impedirá de molestar seus dados.fonte
RequestMappingHandlerMapping
, a propriedade a ser configurada éuseSuffixPatternMatch
(também parafalse
). @ Ted: a questão vinculada menciona que, na versão 3.2, eles esperam adicionar um pouco mais de controle, para que não precise ser tudo ou nada.WebMvcConfigurationSupport
que fornece um gancho simples:public void configurePathMatch(PathMatchConfigurer configurer)
- basta substituí-lo e configurar o caminho que você deseja.O Spring considera que qualquer coisa por trás do último ponto é uma extensão de arquivo, como
.json
ou.xml
e truncar-lo para recuperar o seu parâmetro.Então, se você tem
/{blahName}
:/param
,/param.json
,/param.xml
Ou/param.anything
irá resultar em uma param com valorparam
/param.value.json
,/param.value.xml
ou/param.value.anything
resultará em um parâmetro com valorparam.value
Se você alterar seu mapeamento para
/{blahName:.+}
o sugerido, qualquer ponto, incluindo o último, será considerado como parte do seu parâmetro:/param
resultará em um parâmetro com valorparam
/param.json
resultará em um parâmetro com valorparam.json
/param.xml
resultará em um parâmetro com valorparam.xml
/param.anything
resultará em um parâmetro com valorparam.anything
/param.value.json
resultará em um parâmetro com valorparam.value.json
Se você não se importa com o reconhecimento de extensão, pode desativá-lo substituindo
mvc:annotation-driven
automagic:Então, novamente, se você tiver
/{blahName}
:/param
,/param.json
,/param.xml
Ou/param.anything
irá resultar em uma param com valorparam
/param.value.json
,/param.value.xml
ou/param.value.anything
resultará em um parâmetro com valorparam.value
Nota: a diferença da configuração padrão é visível apenas se você tiver um mapeamento semelhante
/something.{blahName}
. Consulte Problema do projeto Resthub .Se você deseja manter o gerenciamento de extensões, desde o Spring 3.2, também é possível definir a propriedade useRegisteredSuffixPatternMatch do bean RequestMappingHandlerMapping para manter o reconhecimento do sufixoPattern ativado, mas limitado à extensão registrada.
Aqui você define apenas extensões json e xml:
Observe que o mvc: driven-anotation agora aceita uma opção contentNegotiation para fornecer um bean personalizado, mas a propriedade RequestMappingHandlerMapping deve ser alterada para true (padrão false) (consulte https://jira.springsource.org/browse/SPR-7632 )
Por esse motivo, você ainda precisa substituir toda a configuração orientada a anotações do mvc: Abri um ticket para o Spring para solicitar um RequestMappingHandlerMapping personalizado: https://jira.springsource.org/browse/SPR-11253 . Por favor vote se você estiver interessado.
Ao substituir, tome cuidado para considerar também a substituição personalizada do gerenciamento de Execução. Caso contrário, todos os seus mapeamentos de exceção personalizados falharão. Você precisará reutilizar messageCoverters com um bean de lista:
Eu implementei, no projeto de código aberto Resthub do qual faço parte, um conjunto de testes sobre esses assuntos: consulte https://github.com/resthub/resthub-spring-stack/pull/219/files e https: // github.com/resthub/resthub-spring-stack/issues/217
fonte
Tudo após o último ponto é interpretado como extensão de arquivo e cortado por padrão.
No seu XML de configuração da primavera, você pode adicionar
DefaultAnnotationHandlerMapping
e definiruseDefaultSuffixPattern
comofalse
(o padrão étrue
).Então abra o seu XML da primavera
mvc-config.xml
(ou como ele é chamado) e adicioneAgora seu
@PathVariable
blahName
(e todos os outros também) deve conter o nome completo, incluindo todos os pontos.EDIT: Aqui está um link para a API da Primavera
fonte
<mvc:annotation-driven />
se aplicável.Também encontrei o mesmo problema e definir a propriedade como false também não me ajudou. Contudo, a API diz :
Tentei adicionar "/ end" ao meu URL RESTful e o problema desapareceu. Não estou satisfeito com a solução, mas funcionou.
BTW, não sei o que os designers do Spring estavam pensando quando adicionaram esse "recurso" e o ativaram por padrão. IMHO, deve ser removido.
fonte
Usando a classe de configuração Java correta:
fonte
Eu resolvi por esse hack
1) Adicionado HttpServletRequest em @PathVariable como abaixo
2) Obtenha o URL diretamente (neste nível, sem truncamento) na solicitação
Spring MVC @PathVariable com ponto (.) Está sendo truncado
fonte
Acabei de me deparar com isso e as soluções aqui geralmente não funcionavam como eu esperava.
Sugiro usar uma expressão SpEL e vários mapeamentos, por exemplo
fonte
O problema de extensão de arquivo existe apenas se o parâmetro estiver na última parte do URL. mudança
para
e tudo ficará bem de novo
fonte
Se você pode editar o endereço para o qual as solicitações são enviadas, a correção simples seria adicionar uma barra final (e também no
@RequestMapping
valor):então o mapeamento ficaria assim:
Consulte também Spring MVC @PathVariable com ponto (.) Está sendo truncado .
fonte
fonte
adicionar o ":. +" funcionou para mim, mas não até remover os colchetes externos.
value = {"/username/{id:.+}"}
não funcionouvalue = "/username/{id:.+}"
trabalhoEspero ter ajudado alguém:]
fonte
Solução de configuração baseada em Java para impedir o truncamento (usando uma classe não obsoleta):
Fonte: http://www.javacodegeeks.com/2013/01/spring-mvc-customizing-requestmappinghandlermapping.html
ATUALIZAR:
Percebi que havia alguns problemas com a configuração automática do Spring Boot quando usei a abordagem acima (algumas configurações automáticas não são eficazes).
Em vez disso, comecei a usar a
BeanPostProcessor
abordagem. Parecia estar funcionando melhor.Inspirado em: http://ronaldxq.blogspot.com/2014/10/spring-mvc-setting-alwaysusefullpath-on.html
fonte
se você tiver certeza de que seu texto não corresponderá a nenhuma das extensões padrão, use o código abaixo:
fonte
Minha solução preferível para impedir que o Spring MVC @PathVariable seja truncado é adicionar uma barra final no final da variável de caminho.
Por exemplo:
Portanto, a solicitação será semelhante a:
fonte
O problema que você está enfrentando se deve à primavera interpretando a última parte da uri após o ponto (.) Como uma extensão de arquivo como .json ou .xml. Portanto, quando o Spring tenta resolver a variável do caminho, ele simplesmente trunca o restante dos dados depois de encontrar um ponto (.) No final do URI. Nota: isso também acontece apenas se você mantiver a variável path no final do URI.
Por exemplo, considere uri: https: //localhost/example/gallery.df/link.ar
No URL acima firstValue = "gallery.df" e secondValue = "link", o último bit após o. fica truncado quando a variável de caminho é interpretada.
Portanto, para evitar isso, existem duas maneiras possíveis:
1.) Usando um mapeamento regexp
Use uma regex na parte final do mapeamento
Usando +, indicamos qualquer valor após o ponto também fazer parte da variável de caminho.
2.) Adicionando uma barra no final do nosso @PathVariable
Isso incluirá nossa segunda variável, protegendo-a do comportamento padrão do Spring.
3) Substituindo a configuração padrão do webmvc do Spring
O Spring fornece maneiras de substituir as configurações padrão que são importadas usando as anotações @EnableWebMvc . Podemos personalizar a configuração do Spring MVC declarando nosso próprio bean DefaultAnnotationHandlerMapping no contexto do aplicativo e definindo sua propriedade useDefaultSuffixPattern como false. Exemplo:
Lembre-se de que a substituição dessa configuração padrão afeta todos os URLs.
Nota: aqui estamos estendendo a classe WebMvcConfigurationSupport para substituir os métodos padrão. Há mais uma maneira de substituir as configurações de deault implementando a interface WebMvcConfigurer. Para obter mais detalhes sobre isso, leia: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/EnableWebMvc.html
fonte