Условно возвращайте представление тимелеафа с представлением PDF в обработчике Spring MVC

Я разрабатываю приложение для весенней загрузки и использую весеннюю проверку. Необходимо вернуть страницу тимелеафа, если после проверки возникает какая-либо ошибка.

@ResponseBody
@PostMapping(params = "_action_preview_pdf", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<byte[]> getTemplatePDF(@Valid @ModelAttribute(COMMAND_NAME) RxTemplateConfiguration configuration,
                                             BindingResult result) {

    if(result.hasErrors()){
        return VIEW_FORM;  //Error
    }

    ....

    return new ResponseEntity<>(prescriptionHelper.getTemplatePdf(configuration), headers, HttpStatus.OK);

}

получение следующей ошибки:

error: return VIEW_FORM; incompatible types: String cannot be converted to ResponseEntity<byte[]>

Здесь VIEW_FORM = "config-form" это страница тимелефа. Как я могу вернуть страницу тимелеафа?


person Atequer Rahman    schedule 26.09.2018    source источник
comment
Вы всегда можете создать исключение и позволить вашему классу @ControllerAdvice обработать ответ.   -  person Phil    schedule 26.09.2018
comment
Да, я знаю это. Но мне нужно вернуть страницу с сообщением об ошибке. Из вашего комментария я понял, что таким образом вернуть страницу не возможно.   -  person Atequer Rahman    schedule 26.09.2018
comment
Ваш класс @ControllerAdvice может вернуть страницу, вот о чем я говорю. Попытка превратить рендерер шаблона в ResponseEntity<byte[]> кажется чрезмерно сложной. См. spring.io /блог/2013/11/01/   -  person Phil    schedule 26.09.2018
comment
Очевидно ли, что вы вернете ResponseEntity<byte[]>? Если требуется вернуть представление pdf, существуют и другие элегантные решения.   -  person Shafin Mahmud    schedule 26.09.2018
comment
Вместо страницы с ошибкой попробуйте вернуть ответ, который содержит отображаемую страницу. мой ответ см. здесь /50481703/   -  person Supun Dharmarathne    schedule 26.09.2018
comment
@Шафин Махмуд. требование состоит в том, чтобы вернуть представление в формате PDF.   -  person Atequer Rahman    schedule 26.09.2018


Ответы (2)


Решение:

  1. Удален тег @ResponseBody.
  2. Заменен тип возвращаемого значения с ResponseEntity<byte[]> на Object

Код после обновления:

@PostMapping(params = "_action_preview_pdf", produces = MediaType.APPLICATION_PDF_VALUE)
public Object getTemplatePDF(@Valid @ModelAttribute(COMMAND_NAME) RxTemplateConfiguration configuration,
                                         BindingResult result) {

    if(result.hasErrors()){
        return VIEW_FORM;  //Error fixed.
    }

    ....

    return new ResponseEntity<>(prescriptionHelper.getTemplatePdf(configuration), headers, HttpStatus.OK);

}
person Atequer Rahman    schedule 26.09.2018

когда вы возвращаете ResponseEntity<byte[]> из обработчика, вы также не можете вернуться с view-name. Если вы хотите создать представление PDF вместе с другими условными представлениями, есть несколько способов сделать это. Я предпочитаю делать это с BeanNameViewResolver с itexpdf библиотекой

BeanNameViewResolver

Это разрешает представления, объявленные как bean-компоненты. Это означает, что вы можете использовать имя bean-компонента представления в качестве имени представления. В Spring Boot bean-компонент BeanNameViewResolver регистрируется по умолчанию. И для создания представления PDF из bean-компонента вам понадобится этот файл iText API. добавьте это в свой build.gradle

compile group: 'com.itextpdf', name: 'itext7-core', version: '7.1.3'

Чтобы занять BeanNameViewResolver, вам нужно создать bean-компонент, расширяющий AbstratView, где вы будете использовать itex7 для создания PDF-документа.

@Component("reportView")
public class HelloPdfView extends AbstractView {

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {

        response.setHeader("Content-Disposition", "attachment; filename=myReport.pdf");

        // get your bean for generating pdf say it is Report
        Report report = (Report) model.get("report");

        //use IText API
        PdfWriter pdfWriter = new PdfWriter(response.getOutputStream());
        PdfDocument pdf = new PdfDocument(pdfWriter);
        Document pdfDocument = new Document(pdf);

        //do other customization you like
        Paragraph title = new Paragraph(report.getName());
        title.setFont(PdfFontFactory.createFont(StandardFonts.HELVETICA));
        title.setFontSize(18f);
        title.setItalic();
        pdfDocument.add(title);


        //content
        Paragraph content = new Paragraph(report.getContent());
        pdfDocument.add(content);

        pdfDocument.close();

    }
}

Теперь, когда вы просто вызываете его из контроллера, как и другие представления

@PostMapping("/report")
public String showPdf(@Valid @ModelAttribute(COMMAND_NAME) RxTemplateConfiguration configuration, BindingResult result) {
    model.addAttribute("report", getReport()); //get your data

    if(result.hasErrors()){
       return ERROR_VIEW; 
    }


    return "reportView";
}

Смотрите также

person Shafin Mahmud    schedule 26.09.2018
comment
Спасибо за ваш комментарий. Я добавил ответ. - person Atequer Rahman; 26.09.2018