2011-07-21 9 views
13

Mam przypadek użycia, w którym muszę zwrócić plik PDF do użytkownika, który został wygenerowany dla nas. Wydaje się, że muszę w tym przypadku wykorzystać ResponseEntity, ale mam kilka rzeczy, które nie są zbyt jasne.Spring ResponseEntity

  1. Jak mogę przekierować użytkownika - udawajmy, że nie mają uprawnień dostępu do tej strony? Jak mogę przekierować je do osobnego kontrolera?
  2. Czy mogę ustawić kodowanie odpowiedzi?
  3. Czy mogę osiągnąć jeden z tych dwóch bez wprowadzenia HttpResponse jako parametru do Moje RequestMapping?

Używam Spring 3.0.5. Przykładowy kod poniżej:

@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); 
    } 

Naprawdę chciałbym, aby nie ciągnąć w odpowiedzi ... Żaden z moich kontrolerów zrobiłeś do tej pory, a ja nienawidzę mieć do dostosowania go w ogóle.

Odpowiedz

1

Zamiast zajmować się przekierowaniem (są to instancje, które otwieramy w nowych oknach/kartach), zdecydowaliśmy się wyświetlić komunikat o błędzie, który otrzymaliby.

To prawdopodobnie nie zadziała dla wszystkich, ale ze sposobem, w jaki dodamy komunikaty o błędach/statusie, nie byliśmy w stanie utrzymać tych komunikatów w widoku po wystąpieniu wyjątku.

1

Przekierowania są łatwe - dla metody zwracanej przez metodę obsługi Łańcuch, należy poprzedzać znakiem redirect:, jak w przypadku return "redirect:somewhere else".

Nie wiem, dlaczego sprzeciwiasz się obiektowi Response. Czy jest powód? W przeciwnym razie, jeśli po prostu przesyłasz plik PDF w postaci OutputStream na obiekcie HttpServletResponse, to nie musisz zwracać pliku PDF z metody obsługi - wystarczy ustawić strumień PDF w odpowiedzi, który możesz dodać do swojego sygnatura metody obsługi. Zobacz przykład http://www.exampledepot.com/egs/javax.servlet/GetImage.html.

+0

Największym problemem jest to, że korzystają z kilku niestandardowych przechwytujących, aby automatycznie dodać rzeczy z powrotem na żądanie. Potrzebujemy tych przechwytujących, aby uruchomić, gdy użytkownik nie jest w stanie wyświetlić strony, aby wyświetlać komunikaty o błędach - zwrócenie prostego przekierowania String nie powoduje tego. – Scott

+0

Jeśli używasz Interceptorów, jeśli implementujesz 'HandlerInterceptor', masz bezpośredni dostęp do zdarzeń' beforeHandle', 'afterCompletion' i' postHandle' kontrolera cyklu życia, * i * masz bezpośredni dostęp do 'HttpServletRequest Obiekty 'i' HttpServletResponse'. Czy już wdrażasz ten interfejs? – atrain

+0

Te programy obsługi nie są uruchamiane, gdy napotkasz w swoim kodzie wyjątek niezatapiany. – Scott

21

Uwaga, działa to na wiosnę 3.1, nie jestem pewien co do wersji 3.0.5 wiosną, jak zadałem w pierwotnym pytaniu.

W instrukcji returnEntity, w której chcesz obsłużyć przekierowanie, dodaj nagłówek "Location" do ResponseEntity, ustaw ciało na wartość null i ustaw HttpStatus na FOUND (302).

HttpHeaders headers = new HttpHeaders(); 
headers.add("Location", "http://stackoverflow.com"); 

return new ResponseEntity<byte []>(null,headers,HttpStatus.FOUND); 

To będzie Cię od konieczności zmienić typ zwracanej metody kontrolera.

+2

'HttpHeaders' zawiera bezpieczne metody pomocnicze typu, więc' headers.setLocation (uri) 'byłoby bezpieczniejsze. –

+0

Dziękuję. mi to pasuje. – MFH

3

chodzi o przekierowanie, wszystko co musisz zrobić, to zmienić typ zwracany do obiektu:

@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); 
    } 
Powiązane problemy