@MaxLich
java developer

Почему возникает ошибка org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation в выгрузке в эксель?

Здравствуйте. Использую apache poiдля выгрузки в эксель. Также использую Spring. Версии библиотек:
<springframework.boot>2.1.2.RELEASE</springframework.boot>
        <springframework.version>5.1.4.RELEASE</springframework.version>
        <apache-poi.version>4.0.1</apache-poi.version>

При отдаче файла в контроллере возникает ошибка:
ERROR] 2019-05-21 11:50:45.992 [http-nio-9999-exec-2] RestExceptionHandler - Could not find acceptable representation
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation


Вот код моего контроллера:
@RestController
@RequestMapping(produces = "application/vnd.ms-excel")
@Api(tags = {"ExportToMsExcelController"}, description = "Выгрузка в MS Excel"/*, produces = "application/vnd.ms-excel"*/)
public class ExportToMsExcelController {

    private final static Logger logger = LogManager.getLogger(ExportToMsExcelController.class);

    private static final String REQUEST_FILE_PREFIX = "RequestRegistry";

    private CreateRequestXLSXDocumentService createRequestXLSXDocumentService;

    @Autowired
    public void setCreateRequestXLSXDocumentService(CreateRequestXLSXDocumentService createRequestXLSXDocumentService) {
        this.createRequestXLSXDocumentService = createRequestXLSXDocumentService;
    }

    @ResponseStatus(HttpStatus.OK)
    @GetMapping(value = "/requests/list/ms-excel")
    @ApiOperation(value = "Экспортирует таблицу \"Реестр заявлений\" в MS Excel",
            notes = "Экспортирует данные таблицы \"Реестр заявлений\" в файл в формате MS Excel")
    public ResponseEntity<InputStreamResource> exportRequestTable(
            @ApiParam(value = "Optional String sort (example atr-,atr2,atr3)", name = "sort") @RequestParam(value = "sort", required = false) String sort,
            @ApiParam(value = "Optional String search (example evId==541)", name = "search") @RequestParam(value = "search", required = false) String search
    ) {

        Map<String, Object> param = new HashMap<>();

        final long startTime = System.currentTimeMillis();

        Optional.ofNullable(sort).ifPresent(s -> param.put("sort", s));

        Optional.ofNullable(search).ifPresent(s -> param.put("search", s));

        byte[] fileCont;
        try {
            fileCont = createRequestXLSXDocumentService.createXLSXDocument(param);
        } catch (Exception ex) {
            logger.error(ex.toString(), ex);
            throw new RuntimeException(ex.getMessage(), ex);
        }

        final ByteArrayInputStream in = new ByteArrayInputStream(fileCont);

        final String fileName = generateFileName(REQUEST_FILE_PREFIX);

        HttpHeaders headers = new HttpHeaders();
        // set filename in header
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);

        final long endTime = System.currentTimeMillis();

        logger.info("Общее время работы: " + ((endTime - startTime) / 1000) + " сек");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(fileCont.length)
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(new InputStreamResource(in));
    }

    /**
     * Генерирует имя файла
     *
     * @param prefix префикс в имени файла
     * @return сгенерированное имя файла
     */
    private String generateFileName(String prefix) {
        return String.format("%s_%s.xlsx", prefix,
                LocalDateTime.now()
                        .toString()
                        .replace(':', '-')
        );
    }
}
  • Вопрос задан
  • 3074 просмотра
Решения вопроса 1
@MaxLich Автор вопроса
java developer
Проблему решил. Необходимо было добавить свой HttpMessageConverter в конфиг Spring:
...
 @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {

            @Override
            public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(stringConverter());
                converters.add(mappingJackson2HttpMessageConverter());
                converters.add(excelConverter());
            }

...
}

...

    @Bean
    public ResourceHttpMessageConverter excelConverter() {
        final ResourceHttpMessageConverter converter = new ResourceHttpMessageConverter();
        converter.setSupportedMediaTypes(
                List.of(new MediaType("application", "vnd.ms-excel"))
        );
        return converter;
    }


Также немного переделал код метода в контроллере (возвращение значения):
....
      return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(fileCont.length)
                .contentType(new MediaType("application", "vnd.ms-excel"))
                .body(new InputStreamResource(in));
      }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@mystifier
Если в Spring нужно было выдать сгенерированный excel-файл использовал наследование от AbstractXlsxView.

Например public class SbCCDetailsXlsxReport extends AbstractXlsxView
...тут формируем excel...

Потом в конфиге определяем viewresolver:
@Bean
public ViewResolver getXmlViewResolver() {
	XmlViewResolver resolver = new XmlViewResolver();
	resolver.setLocation(new ServletContextResource(servletContext, "/WEB-INF/spring/views.xml"));
	resolver.setOrder(1);
	return resolver;
}


Во views.xml
<bean id="excelViewSbCCDetails" class="somepackage.SbCCDetailsXlsxReport" />


А в контроллере
return new ModelAndView("excelViewSbCCDetails", model);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы