java - 访问 Spring Filter/HandlerInterceptor 多部分和参数(表单字段)
问题描述
我正在编写一个过滤器(也尝试了一个 HandlerInterceptor)并且需要访问 MultiPart 消息的各个部分 - 包括参数(表单字段)和文件。下面的示例代码只为我提供了标头和一般请求信息,对于任何正文/内容请求(例如 getParameter 或 getPart)返回 null。
public class SampleFilter implements Filter {
@Override
public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterchain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
log.info(request.getContentType()); //Works OK
log.info(request.getHeader("X-Some-Header")); //Works OK
log.info(String.valueOf(request.getContentLength())); //Works OK
log.info(request.getParameter("some-form-field")); //Does NOT work
for (Part p : request.getParts()) //Does NOT work
{
log.info("Part:" + p.getName());
}
}
我已经创建了一个 HandlerInterceptor 版本,因为我相信这会在 DespatcherServlet 处理完多部分结构之后在管道中稍后发生。这使我能够从请求中获取表单字段/“参数”,但文件部分仍然没有运气。
public class SampleHandler extends HandlerInterceptorAdapter {
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse resp, Object handler) throws Exception {
log.info(request.getContentType());
log.info(request.getHeader("X-sample-header"));
log.info(String.valueOf(request.getContentLength()));
for (String msg : request.getParameterValues("sample-field"))
{
log.info(msg);
}
log.info(String.valueOf(request.getParts().size())); // Shows 0
for (Part p : request.getParts())
{
log.info("Part:" + p.getName());
}
return true;
到目前为止,我发现的大多数示例都是关于普通控制器中的多部分(见下文,我已经有了)——我专门寻找 Filter 或 HandlerInterceptor 或类似的预控制器钩子。
我有一个现有的 RestController 成功实现了 MultiPart 功能,但不确定如何将此或类似方法应用于过滤器:
@RestController
@RequestMapping (value = {"/**"})
@Slf4j
public class SampleController {
@RequestMapping(value = {"/**"}, method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public ResponseEntity<String> SampleMultipartController(@RequestHeader Map<String, String> httpheaders,
@RequestParam("param1") String param1,
@RequestParam("param2") List<String> param2,
@RequestParam ("file") List<MultipartFile> files) throws IOException {
//etc...
我定义了一个 Commons multipartResolver:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
final int MAX_UPLOAD_SIZE = (100 * 1024 * 1024);
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(MAX_UPLOAD_SIZE + MAX_UPLOAD_SIZE/5);
multipartResolver.setMaxUploadSizePerFile(MAX_UPLOAD_SIZE);
multipartResolver.setMaxInMemorySize(MAX_UPLOAD_SIZE/100);
return multipartResolver;
}
解决方案
通过使用 a 解决了问题HandlerInterceptor
(因为这是发布 DespatcherServlet,似乎 Multipart Resolver 已被应用,而它没有与 Filter 一起使用),并通过删除 Commons Multipart 的东西并改用@MultipartConfig
注释来解决。
@MultipartConfig
public class SampleHandler extends HandlerInterceptorAdapter {
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse resp, Object handler) throws Exception {
可以访问部件/表单数据:
request.getParameter("some-form-field"))
或者如果有多个:
for (String val : request.getParameterValues("some-form-field"))...etc
对于文件:
MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
req.getFile("some-file"))...etc...
或者如果有多个:
MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
for (MultipartFile file : req.getFiles("some-file"))...etc...
也许有更优雅的方法,但这有效。
推荐阅读
- python - 在这种情况下如何使用硒和网络驱动器
- c++ - 没有规则来制作“ui_mediaplayer.h”所需的目标“VLCQtWidgets/WidgetVideo.h”
- javascript - 当您单击 Angular 中的菜单项时,内容不会改变
- javascript - Discord.js 音乐机器人队列命令
- vue.js - 如何将 vue-select 实现为 vue-formulate 中的字段?
- javascript - 悬停时增加项目的宽度和高度
- c# - .NET Core Worker 服务宿主作为 Windows 服务(使用 Coravel 进行任务调度)
- r - 如何将行附加到公式摘要的输出?
- android - Flutter Doctor 无法识别我的 ANDROID_SDK 环境变量
- android - EditText 允许在以编程方式更改 inputType 后进行任何操作