Доступ к составным частям и параметрам Spring Filter / HandlerInterceptor (поля формы) - PullRequest
0 голосов
/ 20 октября 2019

Я пишу Фильтр (также пробовал HandlerInterceptor) и мне нужен доступ к различным частям сообщения MultiPart - включая Параметры (поля формы) и Файлы. Приведенный ниже пример кода дает мне только заголовки и общую информацию запроса, возвращая нулевое значение для любого запроса тела / содержимого, например, getParameter или getPart.

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;


Большинство примеров, которые я нашел, говорят о multipart в обычном контроллере(см. ниже, у меня уже есть это) - я специально ищу либо 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...

И у меня определен multipartResolver Commons:

@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;
    }

Ответы [ 2 ]

0 голосов
/ 20 октября 2019

Устранена проблема с помощью HandlerInterceptor (так как это после DespatcherServlet кажется, что Multipart Resolver был применен, тогда как его не было с фильтром), и , удалив материал 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...

Возможно, есть более элегантные способы, но это сработало.

0 голосов
/ 20 октября 2019

Я бы сделал что-то подобное в 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]));

}

Тогда у вас есть ваши параметры на вашей карте.

...