2

我需要通过spring mvc下载xml文件,并且需要我的应用程序在使用ModelAndView成功下载后导航到另一个jsp页面。下载文件时出现错误

java.lang.IllegalStateException: getOutputStream() 已经为此响应调用

你能帮我解决这个问题吗?

@RequestMapping(value="/download",method = RequestMethod.GET)
public ModelAndView downloadXmlFile(HttpServletRequest request,
        HttpServletResponse response) throws IOException {

   servletcontext context = request.getsession().getservletcontext()

    File downloadFile = new File("c:\\abc.xml");
    FileInputStream inputStream = new FileInputStream(downloadFile);

    // get MIME type of the file
    String mimeType = context.getMimeType(fullPath);
    if (mimeType == null) {
        // set to binary type if MIME mapping not found
        mimeType = "application/octet-stream";
    }
    System.out.println("MIME type: " + mimeType);

    // set content attributes for the response
    response.setContentType(mimeType);
    response.setContentLength((int) downloadFile.length());

    // set headers for the response
    String headerKey = "Content-Disposition";
    String headerValue = String.format("attachment; filename=\"%s\"",
            downloadFile.getName());
    response.setHeader(headerKey, headerValue);

    // get output stream of the response
    OutputStream outStream = response.getOutputStream();

    byte[] buffer = new byte[4096];
    int bytesRead = -1;

    // write bytes read from the input stream into the output stream
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outStream.write(buffer, 0, bytesRead);
    }

    inputStream.close();
    outStream.close();

    return "Success";
}
4

3 回答 3

3
  1. 创建一个 Pojo 类员工
import java.io.Serializable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Book implements Serializable {

String title;
int pages;
String isbn;

public String getTitle() {
    return title;
}

@XmlElement
public void setTitle(String title) {
    this.title = title;
}

public int getPages() {
    return pages;
}

@XmlElement
public void setPages(int pages) {
    this.pages = pages;
}

public String getIsbn() {
    return isbn;
}

@XmlElement
public void setIsbn(String isbn) {
    this.isbn = isbn;
}

}
  1. 创建控制器
import java.io.IOException;
import java.io.ObjectOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SpringMVCController {

@RequestMapping(value = "/downloadXML")
public void downloadXML(HttpServletRequest request,
        HttpServletResponse response) throws IOException, JAXBException {
    Book book = new Book();
    book.setTitle("Lord of the Rings");
    book.setIsbn("Abbbbbb112");
    book.setPages(400);

    try {

        response.setContentType("application/xml");
        response.setHeader("Content-Disposition",
                "attachment; filename=somefile.xml");

        JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        // output pretty printed
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        // writing to a file
        /*ObjectOutputStream out = new ObjectOutputStream(
                response.getOutputStream());*/
        jaxbMarshaller.marshal(book, response.getOutputStream());
        // writing to console
        // jaxbMarshaller.marshal(book, System.out);
        response.flushBuffer();
    } catch (Exception e) {
        e.printStackTrace();
    }

   }

  }


    > 3. **Create a Jsp index.jsp**

 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01    Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring MVC XML Download Example</title>
</head>
<body>
<form:form action="downloadXML" method="post" id="downloadXML">
    <h3>Spring MVC XML Download Example</h3>
    <input id="submitId" type="submit" value="Downlaod XML">
</form:form>
</body>
</html>



    > # Header 1 # 4. Create web.xml 
  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://java.sun.com/xml/ns/javaee"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
  <servlet-name>dispatcher</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
 </servlet-mapping>
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  </context-param>
  <listener>
 <listener-  class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 </web-app>


> 5. Create dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">

 <context:component-scan base-package="com.javahonk.controller" />
 <mvc:annotation-driven/>    

</beans>

** 给出基本包名称**

当我们有时不使用 response.flushBuffer() 时,它不会写入内容

于 2015-07-22T08:59:10.270 回答
0

您不能同时下载和重定向。您已经写入输出流并将其关闭,因此 Spring 无法呈现视图。

您可以模仿许多下载网站所做的事情,下载链接会将您带到“您的下载正在开始”页面,然后在短暂延迟后重定向到下载,但我认为这些设计不好。我总是在下载开始后立即关闭页面并且从不阅读它。

于 2013-09-08T04:57:37.237 回答
0

这个问题是 HTTP 固有的,对于给定的请求,您只能发送一个响应。

因此,当您编写outStream.close();代码时,它可以确保完全发送响应,然后响应流不接受任何其他内容。

这可能会让您认为,您可以删除关闭 hte 流的语句,我会说这是个坏主意。

我会发布一些可以帮助你的东西。

于 2013-09-08T05:11:02.833 回答