这不是重复的referenced question,因为它是特定于Spring的。无论谁添加了(事实发生3年后!)都没有费心去阅读问题或评论帖子,看看真正的答案是什么。接受的答案并不完全是答案,但答案的作者从未回过头来编辑它,就像我问的那样。
鉴于下面的restful方法,Spring 3.1给出了400错误,“客户端发送的请求在语法上是不正确的()”。当token
参数包含URL编码的斜杠(%2F)时,例如“https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim”没有%2F,一切正常。第三方已经在调用此服务(当然!)因此我至少在短期内无法更改发送的内容。关于如何在服务器端解决这个问题的任何想法?
这个问题在https://jira.springsource.org/browse/SPR-8662中得到了很好的描述,尽管这个问题与UriTemplate有关,我不知道这是我能说的。
@RequestMapping("/ws/stuff/**")
@Controller
public class StuffController {
@RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)
public @ResponseBody
String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,
HttpServletRequest request, HttpServletResponse response) {
return handle(resourceId, userName, request, token, modelMap);
}
}
注意:这是在Glassfish 3.1.2上,最初是Grizzly / Glassfish不接受斜杠,但是
-Dcom.sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
解决了这个问题。
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true
似乎没有帮助。
答案 0 :(得分:14)
对于spring-boot,以下是诀窍
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(Application.class, args);
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
答案 1 :(得分:11)
这可能是您的答案:urlencoded Forward slash is breaking URL
我建议不要将其放在路径中,而是将其移至请求参数。
解决方法:
您可以将RequestMapping更改为
@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET)
然后从请求对象手动解析路径变量。
答案 2 :(得分:7)
这是Spring 3.2.4的修复程序(也适用于其他版本)。必须覆盖默认的UrlPathHelper
public class UrlPathHelperFixed extends UrlPathHelper {
public UrlPathHelperFixed() {
super.setUrlDecode(false);
}
@Override
public void setUrlDecode(boolean urlDecode) {
if (urlDecode) {
throw new IllegalArgumentException("Handler [" + UrlPathHelperFixed.class.getName() + "] does not support URL decoding.");
}
}
@Override
public String getServletPath(HttpServletRequest request) {
String servletPath = getOriginatingServletPath(request);
return servletPath;
}
@Override
public String getOriginatingServletPath(HttpServletRequest request) {
String servletPath = request.getRequestURI().substring(request.getContextPath().length());
return servletPath;
}
}
并将其注入Mapping Handler:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="order" value="-1"></property>
<property name="urlPathHelper">
<bean class="com.yoochoose.frontend.spring.UrlPathHelperFixed"/>
</property>
</bean>
经过一天的艰苦努力,它现在适合我: - )
有人向Spring团队建议https://jira.springsource.org/browse/SPR-11101
答案 3 :(得分:5)
对于春季启动应用程序,这对我有用..
版本1 添加
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
到您的 application.properties 文件
版本2 像这样运行你的春季启动应用程序。
static void main(String[] args) {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run this, args
}
版本3或运行您的Java应用程序 -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH =真
这个固定的%2F编码的斜杠路径变量对我来说。
答案 4 :(得分:5)
我找到了这个适合我的解决方案;
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
就在此之前
springApplication.run(参数);
并在Application class
中添加以下代码 @Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
答案 5 :(得分:0)
我们刚刚在我的办公室遇到过这个问题,我们从Solubris said将查询参数放在查询参数中做了以上建议。唯一的额外要求是数据可以有'&amp;'同样,这会弄乱查询参数。我们所要做的就是在文本发送到URL之前对文本进行编码,甚至是“&amp;”过滤掉了。
答案 6 :(得分:0)
另一个答案是对"/"
进行两次编码,这将产生"%252F"
。
在您的映射端点中,Spring会将其解码回"%2F"
。您需要做的就是使用类似以下的方法再解码一次:
URLDecoder.decode(encoded_URL, "UTF-8");
答案 7 :(得分:0)
由于我对iamiddy's answer的编辑被拒绝了,所以我想同时提供Spring Boot 2 +的完整解决方案作为单独的答案。
{5}和Java8不推荐使用WebMvcConfigurerAdapter
,可以直接将其替换为以以下内容结尾的接口WebMvcConfigurer
:
@SpringBootApplication
public class Application extends WebMvcConfigurer {
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(Application.class, args);
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
另外,您还需要配置Spring的(Strict)HttpFirewall
以避免错误消息The request was rejected because the URL contained a potentially malicious String "%2F"
阻止编码斜杠
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
Spring Boot将在可用时使用上述HttpFirewall
Bean-否则可能需要像here所述配置WebSecurity
:
答案 8 :(得分:0)
以下内容解决了BACK_SLASH问题:
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
SpringApplication.run(Application.class, args);
}
但是,可以通过application.yml完成相同的功能。
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true
此设置无效。我没有找到解决这个问题的方法,并且还在寻找它。