Spring ResponseEntity
У меня есть прецедент, когда мне нужно вернуть PDF файл пользователю, который создан для нас. Кажется, что мне нужно сделать, это использовать ResponseEntity в этом случае, но у меня есть несколько вещей, которые не очень понятны.
- Как я могу перенаправить пользователя - допустим, что у них нет прав доступа к этой странице? Как я могу перенаправить их на отдельный контроллер?
- Можно ли установить кодировку ответа?
- Могу ли я достичь любого из этих двух, не введя HttpResponse в качестве параметра в мою RequestMapping?
Я использую Spring 3.0.5. Пример кода ниже:
@Controller
@RequestMapping("/generate/data/pdf.xhtml")
public class PdfController {
@RequestMapping
public ResponseEntity<byte []> generatePdf(@RequestAttribute("key") Key itemKey) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.valueOf("application/pdf"));
if (itemKey == null || !allowedToViewPdf(itemKey)) {
//How can I redirect here?
}
//How can I set the response content type to UTF_8 -- I need this
//for a separate controller
return new ResponseEntity<byte []>(PdfGenerator.generateFromKey(itemKey),
responseHeaders,
HttpStatus.CREATED);
}
Мне бы очень хотелось не отвлечься от ответа... Ни один из моих контроллеров не сделал этого до сих пор, и мне бы очень хотелось, чтобы он его вообще приносил.
Ответы
Ответ 1
Вместо того, чтобы обращаться с перенаправлением (это экземпляры, которые мы открываем в новых окнах/вкладках), мы решили просто отобразить сообщение об ошибке, которое они получили.
Вероятно, это не сработает для всех, но с тем, как мы добавляем сообщения об ошибках/статусах, нам не удалось заставить эти сообщения сохраняться в представлении при возникновении исключения.
Ответ 2
Обратите внимание, что это работает в Spring 3.1, не уверен в Spring 3.0.5, как задано в исходном вопросе.
В ответном ответе ResponseEntity, где вы хотите обработать перенаправление, просто добавьте заголовок "Location" в ResponseEntity, установите тело в null и установите HttpStatus на FOUND (302).
HttpHeaders headers = new HttpHeaders();
headers.add("Location", "http://stackoverflow.com");
return new ResponseEntity<byte []>(null,headers,HttpStatus.FOUND);
Это не даст вам изменить тип возврата метода контроллера.
Ответ 3
Что касается перенаправления, все, что вам нужно сделать, это изменить тип возвращаемого значения на Object:
@Controller
@RequestMapping("/generate/data/pdf.xhtml")
public class PdfController {
@RequestMapping
public Object generatePdf(@RequestAttribute("key") Key itemKey) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.valueOf("application/pdf"));
if (itemKey == null || !allowedToViewPdf(itemKey)) {
return "redirect:/some/path/to/redirect"
}
//How can I set the response content type to UTF_8 -- I need this
//for a separate controller
return new ResponseEntity<byte []>(PdfGenerator.generateFromKey(itemKey),
responseHeaders,
HttpStatus.CREATED);
}
Ответ 4
Переадресации просты - для метода обработчика возвратите String, просто добавьте redirect:
, как в return "redirect:somewhere else"
.
Не уверен, почему вы возражаете против объекта Response
. Есть ли причина? В противном случае, если вы просто передаете PDF как OutputStream
на объект HttpServletResponse
, вам фактически не нужно возвращать PDF из метода вашего обработчика - вам просто нужно установить поток PDF на ответ, который вы может добавить к вашей сигнатуре метода обработчика. См. http://www.exampledepot.com/egs/javax.servlet/GetImage.html для примера.