Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
676 views
in Technique[技术] by (71.8m points)

jersey - MessageBodyWriter not found for media type=application/octet-stream, type=class org.apache.poi.xssf.usermodel.XSSFWorkbook

I have the below class that tries to return some data in the form of an excel spreadsheet. I'm getting the error

MessageBodyWriter not found for media type=application/octet-stream, type=class org.apache.poi.xssf.usermodel.XSSFWorkbook

I've also tried @Produces("application/vnd.ms-excel"), but have gotten similar errors. Anyone have a suggestion as to how I can get this to return a spreadsheet? The last time I got an error message similar to this (complaining that a message body writer couldn't be found for arraylist) I just wrapped it in a generic entity. That trick didn't work this time.

@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();
    }   
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't just use arbitrary objects with the data type application/octet-stream. What you first need to understand is how objects are serialized. This is done with the use of MessageBodyWriters. You can learn more about them in JAX-RS Entity Providers.

How the writer works is that it is passed the entity and the response stream. The writer is supposed to take the entity and write the contents of the entity to the response stream. The writers are looked up by the type of entity we return and the media type expected, in your case you want it to be application/octet-stream.

What the error is saying is that there is no writer to handle the conversion of your XSSFWorkbook. When you talk about application/octet-stream, you're mostly dealing with binary files. XSSFWorkbook is not a binary file. When working with application/octet-stream, you'll mostly be working with byte[], File, InputStream, and StreamingOutput entity types. So if you want to use application/octet-stream, then you would need to change the entity to be one of those types.

I've never used Apache POI, but just going through a quick tutorial, it looks like what you probably want to use for this case is the StreamingOutput, you can just use the XSSFWorkbook#write(OutputStream) method to write the workbook to the 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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...