Return 在 Spring MVC 处理程序中有条件地使用 PDF 视图的 thymeleaf 视图
Return a thymeleaf view conditionally with PDF view in Spring MVC handler
我正在开发 spring 引导应用程序并使用 spring 验证。如果验证后出现任何错误,需要 return thymeleaf 页面。
@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"
这是百里香叶页面。
我如何 return thymeleaf 页面?
解决方案:
- 删除了
@ResponseBody
标签。
- 已将 return 类型从
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);
}
当您从处理程序 returning ResponseEntity<byte[]>
时,也无法使用 view-name return。如果您希望生成 PDF 视图以及有条件的其他视图,有几种方法可以做到这一点。我更喜欢使用 BeanNameViewResolver
和 itexpdf
library
BeanNameViewResolver
这将解析声明为 bean 的视图。这意味着您可以使用视图的 bean 名称作为视图名称。在 Spring Boot 中,默认注册了 BeanNameViewResolver bean。要从 bean 生成 PDF 视图,您需要这个 iText API
。将此添加到您的 build.gradle
compile group: 'com.itextpdf', name: 'itext7-core', version: '7.1.3'
要占用 BeanNameViewResolver
,您需要创建一个扩展 AbstratView
的 bean,您将在其中使用 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";
}
另见
我正在开发 spring 引导应用程序并使用 spring 验证。如果验证后出现任何错误,需要 return thymeleaf 页面。
@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"
这是百里香叶页面。
我如何 return thymeleaf 页面?
解决方案:
- 删除了
@ResponseBody
标签。 - 已将 return 类型从
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);
}
当您从处理程序 returning ResponseEntity<byte[]>
时,也无法使用 view-name return。如果您希望生成 PDF 视图以及有条件的其他视图,有几种方法可以做到这一点。我更喜欢使用 BeanNameViewResolver
和 itexpdf
library
BeanNameViewResolver
这将解析声明为 bean 的视图。这意味着您可以使用视图的 bean 名称作为视图名称。在 Spring Boot 中,默认注册了 BeanNameViewResolver bean。要从 bean 生成 PDF 视图,您需要这个 iText API
。将此添加到您的 build.gradle
compile group: 'com.itextpdf', name: 'itext7-core', version: '7.1.3'
要占用 BeanNameViewResolver
,您需要创建一个扩展 AbstratView
的 bean,您将在其中使用 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";
}