Spring Security,Spring Webflow,文件上传和UTF-8问题
I have a problem very similar to the one described here: File Upload using Spring WebFlow 2.4.0, parameter not binded, but that one didn't mention anything about UTF-8 issues. I'm using Spring Framework 4.1.6, Spring Security 4.0.2 and Spring Webflow 2.4.2.
据我所知,它围绕StandardServletMultipartResolver
与CommonsMultipartResolver
旋转,但是我不确定.如果使用CommonsMultipartResolver
,则可以在任何页面上上传文件,但Webflow页面除外,并且UTF-8编码在所有页面上都可以正常工作.但是,在Webflow页面上,尝试访问该文件会引发异常.如果我使用StandardServletMultipartResolver
,则所有文件上传工作(包括Webflow)都可以正常工作,但是在任何具有UTF-8字符(例如caractère)的页面上,我都会得到垃圾.
It revolves around StandardServletMultipartResolver
vs. CommonsMultipartResolver
as far as I can tell, but I'm not sure. If I use CommonsMultipartResolver
I can upload files on any page except for Webflow pages fine and UTF-8 encoding works as well on all pages. However on the Webflow pages an exception is thrown trying to access the file . If I use StandardServletMultipartResolver
then all of the file uploads work, including Webflow, but on any page that has a UTF-8 character, e.g., caractère, I get garbage.
更奇怪的是,当我使用Commons解析器时,我在FireBug中看到文件正在发布.另外,如果我调试了来自Webflow的RequestContext
,我还可以看到文件在请求的深处埋藏了4个层次.通用解析程序的代码(有关标准解析程序代码,请参见帖子结尾):
The wierd thing is I can see in FireBug that the file is being posted when I use the commons resolver. Also, if I debug the RequestContext
coming from Webflow I can also see the file buried 4 levels deep in requests. The code for the common resolver (see end of post for the standard resolver code):
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new DefaultMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
那么,这是Spring Security问题还是Spring Webflow问题?我怀疑如果我可以正确地将RequestContext强制转换到上面,公共解析器就可以工作,但是我尝试了很多没有运气的组合.任何对此的指导将不胜感激.
So, is this a Spring Security issue or a Spring Webflow problem? I suspect the commons resolver would work if I could cast the RequestContext above correctly, but I've tried numerous combinations with no luck. Any guidance on this would be greatly appreciated.
以下是一些相关的配置和代码:
Here are some relevant configurations and code:
WebMvcConfig
@Bean
public CommonsMultipartResolver filterMultipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
SecurityConfig
@Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
http
//.csrf().disable()
.addFilterBefore(characterEncodingFilter, CsrfFilter.class)
...more settings...
SecurityInitializer
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
Webflow操作
<action-state id="uploadFile">
<evaluate expression="fileActions.uploadFile(recipe, flowRequestContext)"/>
<transition to="review"/>
</action-state>
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
MultipartHttpServletRequest multipartRequest = new StandardMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
结果证明您可以强制转换RequestContext以获得底层的MultipartHttpServletRequest
,但这并不漂亮.这就是我最终得到的:
Turns out you can cast the RequestContext to get at the underlying MultipartHttpServletRequest
but it's not pretty. Here's what I ended up with:
上传文件方法
public FileResult uploadFile(Recipe recipe, RequestContext requestContext) {
logger.debug("uploadFile");
ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
SecurityContextHolderAwareRequestWrapper wrapper1 = (SecurityContextHolderAwareRequestWrapper)context.getNativeRequest();
HttpServletRequestWrapper wrapper2 = (HttpServletRequestWrapper)wrapper1.getRequest();
FirewalledRequest firewall = (FirewalledRequest)wrapper2.getRequest();
MultipartHttpServletRequest multipartRequest = (DefaultMultipartHttpServletRequest)firewall.getRequest();
MultipartFile file = multipartRequest.getFile("file");
...rest of code to save the file...
使用此方法,我可以保留CommonsMultipartResolver
,无论是否使用Webflow,应用程序中所有文件的上载都可以正常工作,而且UTF-8和字符处理都没有问题.
Using this I get to keep the CommonsMultipartResolver
, all file uploads in the app work whether Webflow or not, and I have no issues with UTF-8 and character mangling.
我对此解决方案并不满意(即使它可以工作),因为它依赖于将来可能会更改的特定请求嵌套(?).我很想知道是否还有其他人遇到了相同的UTF-8问题以及他们是如何解决的,但是现在我要测试一下这个问题,然后继续.
I'm not particularly happy with this solution (even though it works) since it's dependent upon a specific nesting of requests that could change in the future(?). I'm be interested if anyone else has run into the same UTF-8 issue and how they solved it, but for now I'm going to test the heck out of this and move on.