Java 访问Spring Filter/HandlerInterceptor多部分零件和参数(表单字段)

Java 访问Spring Filter/HandlerInterceptor多部分零件和参数(表单字段),java,spring,spring-boot,spring-mvc,servlet-filters,Java,Spring,Spring Boot,Spring Mvc,Servlet Filters,我正在编写一个过滤器(也尝试了HandlerInterceptor),需要访问多部分消息的各个部分,包括参数(表单字段)和文件。下面的示例代码只提供标题和一般请求信息,对于任何正文/内容请求(例如getParameter或getPart),都返回null public class SampleFilter implements Filter { @Override public void doFilter (ServletRequest req, ServletResponse

我正在编写一个过滤器(也尝试了HandlerInterceptor),需要访问多部分消息的各个部分,包括参数(表单字段)和文件。下面的示例代码只提供标题和一般请求信息,对于任何正文/内容请求(例如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版本,因为我相信这会在Dispatcherservlet处理多部分结构之后在管道中发生。这使我能够从请求中获取表单字段/“参数”,但仍然无法处理文件部分

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;


到目前为止,我发现的大多数示例都在讨论普通控制器中的多部分(请参见下文,我已经有了这个示例)-我专门寻找一个过滤器或HandlerInterceptor或类似的预控制器挂钩

我有一个成功实现多部分功能的现有RestController,但不确定如何将此方法或类似方法应用于过滤器:

@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...


doFilter
中,我会这样做:

@Override
public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterchain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    URI uri = new URI(request.getRequestURI());

    Map<String, String> map = Arrays.stream(uri.getRawQuery().split("&"))
            .collect(Collectors.toMap(param -> param.split("=")[0], param -> param.split("=")[0]));

}
@覆盖
public void doFilter(ServletRequest req、ServletResponse resp、FilterChain FilterChain)抛出IOException、ServletException{
HttpServletRequest请求=(HttpServletRequest)请求;
HttpServletResponse=(HttpServletResponse)resp;
URI=新URI(request.getRequestURI());
Map Map=Arrays.stream(uri.getRawQuery().split(&)))
.collect(Collectors.toMap(param->param.split(“=”[0]),param->param.split(“=”[0]);
}

然后您的地图中就有了您的参数。

通过使用
HandlerInterceptor
解决了问题(由于这是post Dispatcherservlet,似乎应用了多部分解析器,而没有使用过滤器),删除Commons多部分内容并使用
@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;
for (MultipartFile file : req.getFiles("some-file"))...etc...
至于档案:

MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
req.getFile("some-file"))...etc...
或者如果有多个:

for (String val : request.getParameterValues("some-form-field"))...etc
MultipartHttpServletRequest req = (MultipartHttpServletRequest) request;
for (MultipartFile file : req.getFiles("some-file"))...etc...

也许还有更优雅的方法,但这很管用。

我正在寻找在多部分中传递的表单字段以及文件,而不是uri参数。问题是访问多部分的部分-其中一些不是文件。