如何在 Spring mvc 中下载 pdf 文件并重定向到主页
Posted
技术标签:
【中文标题】如何在 Spring mvc 中下载 pdf 文件并重定向到主页【英文标题】:How to download pdf file and redirect to home page in Spring mvc 【发布时间】:2020-06-09 11:06:57 【问题描述】:以下代码可以正常工作,没有错误,但不能按要求工作..
问题 1:我想下载 pdf 文件并重定向到主页 页面(url:../)。当我导航到 url(../admin/generate_pdf)
问题 2:当我取消注释 Pdfdemo.java 中的注释行时 给我一个找不到错误 404 页面。
Pdfdemo.java
public class Pdfdemos
private static String USER_PASSWORD = "password";
private static String OWNER_PASSWORD = "lokesh";
public String generate_pdf()
try
String file_name="d:\\sanjeet7.pdf";
Document document= new Document();
PdfWriter writer=PdfWriter.getInstance(document, new FileOutputStream(file_name));
// writer.setEncryption(USER_PASSWORD.getBytes(),
// OWNER_PASSWORD.getBytes(), PdfWriter.ALLOW_PRINTING |PdfWriter.ALLOW_ASSEMBLY|
// PdfWriter.ALLOW_COPY|
// PdfWriter.ALLOW_DEGRADED_PRINTING|
// PdfWriter.ALLOW_FILL_IN|
// PdfWriter.ALLOW_MODIFY_ANNOTATIONS|
// PdfWriter.ALLOW_MODIFY_CONTENTS|
// PdfWriter.ALLOW_SCREENREADERS|
// PdfWriter.ALLOW_ASSEMBLY|
// PdfWriter.ENCRYPTION_AES_128, 0);
document.open();
document.add(new Paragraph(" "));document.add(new Paragraph(" "));
String days_in_week[]= "monday","tuesday","webnesday","thursday","friday","saturday";
int period=8;
String user="springstudent";
String pass="springstudent";
String jdbcUrl="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false";
String driver="com.mysql.jdbc.Driver";
Connection myconn=DriverManager.getConnection(jdbcUrl,user,pass);
PreparedStatement ps=null;
ResultSet rs=null;
String query="select * from class_t";
ps=myconn.prepareStatement(query);
rs=ps.executeQuery();
while(rs.next())
Paragraph para=new Paragraph("Time table for class"+rs.getString("class")+rs.getString("section"));
document.add(para);
System.out.println(rs.getInt("id"));
PdfPTable table=new PdfPTable(period+1);
for(int i=0;i<days_in_week.length;i++)
for(int j=0;j<period+1;j++)
if(j==5)
table.addCell("recess");
else
table.addCell("this is "+j);
document.add(table);
document.newPage();
document.close();
System.out.println("finish");
return file_name;
catch(Exception e)
System.out.println(e);
return null;
Generate_pdf_controller.java
@Controller
@RequestMapping("/admin/generate_pdf")
public class Generate_pdf_Controller
@GetMapping("/online")
public String generating_pdf(Model theModel)
System.out.println("hello");
CustomerServiceImpl pal=new CustomerServiceImpl();
Pdfdemos pal1=new Pdfdemos();
String xx=pal1.generate_pdf();
return "redirect:/";
【问题讨论】:
查看此解决方案:***.com/questions/17955777/… 我可以重定向,但不能在 sae 时下载和重定向.. 您可以在下载 PDF 后使用 Java Script 从网页重定向。 我怎样才能下载它?...第二个问题呢... 在下面查看我的答案。 【参考方案1】:创建和下载 PDF 的简化版:
@Service
public class PdfService
public InputStream createPdf() throws Exception
ByteArrayOutputStream out = new ByteArrayOutputStream();
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.getInstance(document, out);
writer.setEncryption("user_password".getBytes(), "owner_password".getBytes(),
PdfWriter.ALLOW_PRINTING |
PdfWriter.ALLOW_ASSEMBLY |
PdfWriter.ALLOW_COPY |
PdfWriter.ALLOW_DEGRADED_PRINTING |
PdfWriter.ALLOW_FILL_IN |
PdfWriter.ALLOW_MODIFY_ANNOTATIONS |
PdfWriter.ALLOW_MODIFY_CONTENTS |
PdfWriter.ALLOW_SCREENREADERS |
PdfWriter.ALLOW_ASSEMBLY |
PdfWriter.ENCRYPTION_AES_128, 0);
document.open();
document.add(new Paragraph("My example PDF document"));
// some logic here
document.close();
return new ByteArrayInputStream(out.toByteArray());
@Controller
@RequestMapping("/admin/generate_pdf")
public class PdfController
@Autowired
private PdfService pdfService;
@GetMapping("/online")
public void generatePdf(HttpServletResponse response) throws Exception
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=\"mydocument.pdf\"");
InputStream pdf = pdfService.createPdf();
org.apache.commons.io.IOUtils.copy(pdf, response.getOutputStream());
response.flushBuffer();
重定向怎么样,正如我在 cmets 中所说,您可以在前端使用 JS 来实现(在调用 /admin/generate_pdf/online
url 之后)。您不能同时下载文件和进行刷新/重定向。
【讨论】:
【参考方案2】:只是为了获取pdf(从本地文件系统下载到浏览器中),这段代码就足够了:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/admin/generate_pdf")
public class PdfController
@GetMapping(value = "/online", /*this is "nice to have" ->*/ produces = MediaType.APPLICATION_PDF_VALUE)
@ResponseBody // this is important, as the return type byte[]
public byte[] generating_pdf() throws IOException //exception handling...
System.out.println("hello");//logging
// re-generate new file if needed (thread-safety!)...
// ..and dump the content as byte[] response body:
return Files.readAllBytes(Paths.get("d:\\sanjeet7.pdf"));
...如果您需要“刷新”,您可以“重写”文件/重新调用您的服务,但仍然可能不是“线程最安全”的解决方案。
编辑:无需进一步配置(端口/上下文根/...),您应该通过以下方式访问:http://localhost:8080/admin/generate_pdf/online
如果您想“操作更接近字节”并且使用void
返回类型/没有@ResponseBody
并且想要额外的重定向(待测试),我认为这应该仍然有效:
@Controller
public class ...
@GetMapping(value = ..., produces ...)
//no request body, void return type, response will be autowired and can be handled
public void generatePdf(javax.servlet.http.HttpServletResponse response) throws ...
java.io.OutputStream outStr = response.getOutputStream();
// dump from "somewhere" into outStr, "finally" close.
outStr.close();
//TO BE TESTED:
response.sendRedirect("/");
..甚至(返回“视图名称”+对输出流进行操作):
@GetMapping(value = ..., produces = "application/pdf")
//return a "view name" (!), and you can inject (only) the outputstream (without enclosing response)
public String generatePdf(java.io.OutputStream outputstream) throws...
// ... do your things on outputstream, IOUtils is good...
// close the stream(?)
// ..and
return "redirect:/"; // to a redirect or a view name.
// .... (in a "spring way", which could also save you some "context path problems"
...
【讨论】:
#second_problem:检查/测试我的编辑,@sanjeetpal ...在前端,您可能有一些选择。 404 也可能是“缺少错误页面”(对于另一个错误代码/问题) ..那么,您还需要(添加到方法签名)HttpServletRequest request
,并使用request.getContextPath()
(=/project_name
)(或从“其他地方”获取)
nono,request.getContextPath()
是环境安全的/在任何地方都可以工作/来自浏览器(请不要将我钉在负载平衡和代理案例中)...但仍然重新考虑来完成此请求带有重定向。 (您提供“重定向代码”,但内容......这与重定向的目的不一致)..也许“新标签”就足够了......所有浏览器
"Content-Disposition"
(filename, size, ... 查看 ilia 的回复) 标头的使用也可能对某些浏览器(IE!?)有一些影响!以上是关于如何在 Spring mvc 中下载 pdf 文件并重定向到主页的主要内容,如果未能解决你的问题,请参考以下文章
Spring+MYBatis企业应用实战pdf高清版免费下载