MessageBodyWriter не найден для типа носителя = application / octet-stream, type = class org.apache.poi.xssf.usermodel.XSSFWorkbook - PullRequest
0 голосов
/ 18 мая 2018

У меня есть класс ниже, который пытается вернуть некоторые данные в виде таблицы Excel.Я получаю сообщение об ошибке

MessageBodyWriter не найден для типа носителя = application / octet-stream, type = class org.apache.poi.xssf.usermodel.XSSFWorkbook

Я также пытался @Produces("application/vnd.ms-excel"), но получил похожие ошибки.У кого-нибудь есть предложение относительно того, как я могу получить это, чтобы вернуть электронную таблицу?В прошлый раз, когда я получил сообщение об ошибке, похожее на это (жалуясь на то, что не удалось найти автора тела сообщения для arraylist), я просто обернул его в общий объект.Этот трюк на этот раз не сработал.

@PermitAll
@Path("uploadWorkbook")
public class ExcelUploadResource {

    @Context
    ResourceContext resourceContext;

    @Inject
    JobService jobService;

    @GET
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response list() {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Job definitions");

        int rowNum = 0;
        for(Job job : jobService.list()){
            Row row = sheet.createRow(rowNum++);
            int cellNum = 0;
            for(String field : job.toList()){
                Cell cell = row.createCell(cellNum++);
                cell.setCellValue(field);
            }
        }

        GenericEntity<XSSFWorkbook> entity = new GenericEntity<XSSFWorkbook>(workbook) {};

        ResponseBuilder response = Response.ok(entity);
        response.header("Content-Disposition",
            "attachment; filename=jobs.xls");
        return response.build();
    }   
}

1 Ответ

0 голосов
/ 18 мая 2018

Вы не можете просто использовать произвольные объекты с типом данных application/octet-stream.Сначала вам нужно понять, как объекты сериализуются.Это делается с использованием MessageBodyWriter с.Вы можете узнать о них больше в Поставщиках сущностей JAX-RS .

. Как работает писатель, он передает сущность и поток ответа.Предполагается, что средство записи берет объект и записывает содержимое объекта в поток ответов.Авторы ищут тип сущности, которую мы возвращаем, и ожидаемый тип носителя, в вашем случае вы хотите, чтобы он был application/octet-stream.

. Что говорит ошибка, так это то, что для записиконверсия вашего XSSFWorkbook.Когда вы говорите о application/octet-stream, вы в основном имеете дело с двоичными файлами.XSSFWorkbook не является двоичным файломПри работе с application/octet-stream вы в основном будете работать с типами сущностей byte[], File, InputStream и StreamingOutput.Поэтому, если вы хотите использовать application/octet-stream, вам нужно будет изменить сущность на один из этих типов.

Я никогда не использовал Apache POI, но, просто пройдя краткое руководство, похоже,то, что вы, вероятно, хотите использовать для этого случая, это StreamingOutput, вы можете просто использовать метод XSSFWorkbook#write(OutputStream), чтобы записать книгу в StreamingOutput

public Response getExcelFile() {
    XSSFWorkbook workbook = new XSSFWorkbook();
    ...
    StreamingOutput output = new StreamingOutput() {
        @Override
        public void write(OutputStream out)
                throws IOException, WebApplicationException {

            workbook.write(out);
            out.flush();
        }
    };
    return Response.ok(output)
            .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=jobs.xls")
            .build();
}
...