Pergunta

Vamos supor que eu tenho string como, para ser uma parte da minha URL, vamos dizer assim '= & / # +%?':

example.com/servletPath/someOtherPath/myString/something.html?a=b&c=d#asdf

onde myString é a seqüência acima. Eu codificado parte crítica de modo olhares URL como

example.com/servletPath/someOtherPath/%3D%26%3F%2F%3B%23%2B%25/something.html?a=b&c=d#asdf

Até aí tudo bem.

Quando eu estou no servlet e eu lê request.getRequestURI(), request.getRequestURL() ou request.getPathInfo(), o valor retornado é já decodificado, então eu ficar strilng como

someOtherPath/=&?/;#+%/something.html?a=b&c=d#asdf

e eu não pode diferenciar entre caracteres especiais reais e aqueles codificados.

Eu já resolveu um problema particular, proibindo acima caracteres ao todo, que funciona nesta situação, mas eu ainda me pergunto há alguma maneira de obter URL undecoded na classe servlet.

MAIS UMA EDIT: Quando eu bati este problema última noite eu estava cansado demais para perceber o que está realmente acontecendo, que é ainda mais bizarro eu servlet mapeados, digamos / servletPath / * depois que eu possa colocar o que quiser e buscar o meu servlet responder dependendo o resto de um caminho, exceto quando há 2F% no caminho. Nesse caso, solicitação nunca atinge o servlet , e eu recebo 404! Se eu colocar '/' em vez de% 2F ele funciona OK. Estou executando o Tomcat 6.0.14 em Java 1.6.0-04 no Linux.

Foi útil?

Solução

Há uma diferença fundamental entre '% 2F' e '/', tanto para o navegador eo servidor.

O HttpServletRequest especificação diz (sem qualquer lógica, AFAICT):

  • getContextPath: não decodificado
  • getPathInfo: decodificado
  • getPathTranslated: não decodificado
  • getQueryString: não decodificado
  • getRequestURI: não decodificado
  • getServletPath: decodificado

O resultado da getPathInfo () deve ser decodificado, mas o resultado de getRequestURI () não deve ser decodificado. Se for, o seu recipiente Servlet está quebrando a especificação (como Wouter Coekaerts e Francois Gravel apontou corretamente). Qual versão Tomcat você está correndo?

Fazendo as coisas ainda mais confusas, versões atuais do Tomcat rejeitar caminhos que contêm codificações de determinados caracteres especiais, por razões de segurança .

Outras dicas

Se houver um %2F no decodificado url, isso significa que o codificado url %252F contido.

Desde %2F é / Porque não basta dividir em "\/" e não se preocupar com a codificação de URL?

De acordo com a Javadoc , getRequestURI não deve decodificar a seqüência. Por outro lado, getServletPath retornar uma string decodificada. Eu testei isso usando localmente Jetty e comporta-se como descrito no doc.

Portanto, não pode ser outra coisa em jogo na sua situação uma vez que o comportamento que você está descrevendo não coincide com a documentação do Sol.

Parece que você está tentando fazer Resty alguma coisa (usar Jersey). Pode é você apenas analisar off as partes esquerda e à direita da URL para obter os dados que você está procurando?

url.substring (startLength, url.length - endLength);

Update: esta resposta foi originalmente erroneamente afirmando que '/' e '% 2F' em um caminho deve ser sempre tratados da mesma forma. Eles são de fato diferente porque um caminho é uma lista de / segmentos -separated.

Você não deveria ter que fazer a diferença entre um carácter codificado codificado e não em a parte do caminho do URL. Não há personagem dentro do caminho que pode ter um significado especial em um URL. Por exemplo. '% 2F' deve ser interpretado o mesmo que '/', e um navegador acessando tal URL um é livre para substituir um pelo outro como lhe aprouver. Fazendo a diferença entre eles está quebrando o padrão de como URLs são codificados.

No URL completa, você deve fazer a diferença entre caracteres de escape e não de fuga, por diferentes razões, incluindo:

  • Para ver onde termina a parte do caminho. Porque um? codificado no caminho não deve ser visto como o fim.
  • Dentro da string de consulta. Porque parte do valor de um parâmetro pode conter '&' ou '=', ...
  • Dentro de um caminho, um '/' separa-se dois segmentos durante a '% 2F' pode ser contido dentro de um segmento

Java lida bem com os dois primeiros casos:

  • getPathInfo() que retorna apenas a parte do caminho, decodificado
  • getParameter(String) a partes de acesso da parte de consulta

Ele não lida tão bem com o terceiro caso. Se você quiser fazer uma diferença entre '/' como a separação de dois segmentos de caminho e um '/' dentro de um segmento de caminho (% 2F), então você não pode consistentemente representar o caminho como um string decodificada. Pode quer representá-lo como uma cadeia de caracteres codificados (por exemplo, "foo / bar% 2Fbaz"), ou como uma lista de segmentos descodificados (por exemplo, "foo", "bar / baz"). Mas porque getPathInfo () promessas API para fazer isso (uma string decodificada), ele não tem escolha a não ser tratar '/' e '% 2F' como o mesmo.

Para aplicações web habituais, este é apenas multa. Se você está no caso raro onde você realmente precisa para fazer a diferença, você pode fazer sua própria análise do URL, ficando a versão crua com getRequestURI(). Se isso se dá o URL decodificado como você diz, então isso significa que há um bug na implementação servlet que você está usando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top