ddd
ddd

Reputation: 5029

HTTP 406 downloading a file with rest call

I followed this tutorial to implement rest API with Spring Boot for downloading files (xml format).

My controller class is as follows:

@RestController
public class RistoreController {
    @Autowired
    private RistoreService ristoreService;

    @RequestMapping( 
            value = "/ristore/foundation/{trf}", 
            method = RequestMethod.GET, 
            produces = "application/xml")
    public ResponseEntity<InputStream> getXMLById(@PathVariable("trf") String trf) throws IOException {
        InputStream inputStream = ristoreService.findByTRF(trf);
        return ResponseEntity
                .ok()
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(inputStream);
    }
}

I have service interface RistoreService autowired in the controller and Bean class for that service looks like this:

@Service
public class RistoreServiceBean implements RistoreService {
    public InputStream findByTRF(String trf) throws IOException {
        String filePath = "/Users/djiao/Box Sync/Work/Projects/RIStore/foundation/foundation_new/" + trf + ".xml";
        File file = new File(filePath);
        return new FileInputStream(file);
    }
}

I tested the application using the following curl command:

curl -i -H "Accept: application/xml" http://localhost:8080/ristore/foundation/TRF133672_1455294493597

However, I got 406 error, "Not Acceptable". Something wrong with the file format?

Upvotes: 1

Views: 2855

Answers (2)

Hassam Abdelillah
Hassam Abdelillah

Reputation: 2304

Try to change the definition of the controller that way

        @RequestMapping(value = "/ristore/foundation/{trf}", method = RequestMethod.GET, produces = "application/xml")
    public ResponseEntity<InputStreamResource> downloadXMLFile(@PathVariable("trf") String trf)
            throws IOException {

        // Optinal headers configuration 

HttpHeaders headers = new HttpHeaders();

        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");


        // get the inputStream

    InputStream xmlFileInputStream = ristoreService.findByTRF(trf);



        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(xmlFileInputStream));
    }

Then your service class would be :

 @Service
public class RistoreServiceBean implements RistoreService {
    public InputStream findByTRF(String trf) throws IOException {
        String filePath = "/Users/djiao/Box Sync/Work/Projects/RIStore/foundation/foundation_new/" + trf + ".xml";
        File file = new File(filePath);
        return new FileInputStream(file);
    }
}

406 Not Acceptable The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.

That means that the inputstream you return must be considered as a resource as soon as you have a REST controller.

Upvotes: 2

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16152

The following two lines in your code contradict each other:

            .contentType(MediaType.parseMediaType("application/octet-stream"))

and

        produces = "application/xml")

Upvotes: 1

Related Questions