Reputation: 2526
I have the following controller:
@RequiredArgsConstructor
@RestController
public class OwnerViewController implements ApiOwnerViewController {
private static final String TEXT_CSV = "text/csv";
private final PrivateOwnerFacade privateOwnerFacade;
@PostMapping("/boat/v1/private-owners/search")
public OwnerViewResponse searchOwners(@Valid @RequestBody SearchOwnersRequest request,
Pageable pageable) {
return privateOwnerFacade.findOwners(request, pageable);
}
@PostMapping(value = "/boat/v1/private-owners/search", produces = TEXT_CSV)
public ResponseEntity<Resource> exportToCsv(@Valid @RequestBody SearchOwnersRequest request, Pageable pageable)
throws IOException {
So I have two methods mapped to the same url and that both accept POST request BUT produce different content type - the first one produces application/json
while the second produces text/csv
.
Then, when I'm trying to make a request and set header
Accept: text/csv
I get 406 from the server.
I wonder if it is really possible to do such things with spring? Or is the only way to change second method so that it accepts GET
requests?
Thanks
Upvotes: 4
Views: 4675
Reputation: 2526
@RequiredArgsConstructor
@RestController
public class SearchController {
@PostMapping(value = "/search", produces = {APPLICATION_JSON})
public SearchResponse search(@Valid @RequestBody SearchRequest request,
Pageable pageable) {
}
@PostMapping(value = "/search", produces = {TEXT_CSV})
public ResponseEntity<Resource> export(@Valid @RequestBody SearchRequest request, Pageable pageable) throws IOException {
}
}
Upvotes: 3
Reputation: 12953
the problem is that request with text/csv matches both endpoints.
you can use negative values on the annotation, so the first one will match only non-text/csv requests:
@PostMapping(value = "/boat/v1/private-owners/search", produces = "!text/csv")
public OwnerViewResponse searchOwners(@Valid @RequestBody SearchOwnersRequest
request,
Pageable pageable) {
return privateOwnerFacade.findOwners(request, pageable);
}
Upvotes: 1
Reputation: 6170
Just use one Method with a @PostMapping, return a response entity and dynamically set the Content-Type-Response-Header.
@RestController
public class TestController {
@GetMapping("/api-endpoint")
public ResponseEntity<String> method(@RequestParam("produces") String produces) {
HttpHeaders responseHeaders = new HttpHeaders();
if (produces.equals("text/csv")) {
responseHeaders.setContentType(new MediaType("text", "csv"));
return new ResponseEntity<String>("foo;bar", responseHeaders, HttpStatus.OK);
} else {
responseHeaders.setContentType(new MediaType("application", "json"));
return new ResponseEntity<String>("{\"foo\": \"bar\"}", responseHeaders, HttpStatus.OK);
}
}
}
Upvotes: 0