M
M
MaxLich2019-05-21 12:03:55
Java
MaxLich, 2019-05-21 12:03:55

Why does the error org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation occur in Excel export?

Hello. I use apache poiit to upload to excel. I also use Spring. Library versions:

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

When submitting a file in the controller, an error occurs:
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

Here is my controller code:
@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(':', '-')
        );
    }
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
MaxLich, 2019-05-21
@MaxLich

Solved the problem. It was necessary to add your own HttpMessageConverterto the config 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;
    }

I also slightly changed the method code in the controller (returning a value):
....
      return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(fileCont.length)
                .contentType(new MediaType("application", "vnd.ms-excel"))
                .body(new InputStreamResource(in));
      }
}

M
mystifier, 2019-05-21
@mystifier

If in Spring it was necessary to issue a generated excel file, I used inheritance from AbstractXlsxView.
For example public class SbCCDetailsXlsxReport extends AbstractXlsxView
...here we form excel...
Then we define viewresolver in the config:

@Bean
public ViewResolver getXmlViewResolver() {
  XmlViewResolver resolver = new XmlViewResolver();
  resolver.setLocation(new ServletContextResource(servletContext, "/WEB-INF/spring/views.xml"));
  resolver.setOrder(1);
  return resolver;
}

In views.xml
And in the controller
return new ModelAndView("excelViewSbCCDetails", model);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question