Java 无法调用getWriter(),已调用getOutputStream()

Java 无法调用getWriter(),已调用getOutputStream(),java,spring,jsp,spring-mvc,servlets,Java,Spring,Jsp,Spring Mvc,Servlets,我有一个使用SpringMVC的程序。我编写了两个控制器,第一个用于导入数据,第二个用于生成报告。我在生成控制器时遇到问题。当用户单击“生成”按钮时,我想生成报告,将报告保存在服务器硬盘上,并将报告发送给用户。当我试图在硬盘上保存报告时,出现非法状态异常:无法调用getWriter(),getOutputStream()已被调用。我寻找答案,但找不到匹配的答案。这是我的发电机控制器代码: @RequestMapping(value = "/generate", method = RequestM

我有一个使用SpringMVC的程序。我编写了两个控制器,第一个用于导入数据,第二个用于生成报告。我在生成控制器时遇到问题。当用户单击“生成”按钮时,我想生成报告,将报告保存在服务器硬盘上,并将报告发送给用户。当我试图在硬盘上保存报告时,出现非法状态异常:无法调用getWriter(),getOutputStream()已被调用。我寻找答案,但找不到匹配的答案。这是我的发电机控制器代码:

@RequestMapping(value = "/generate", method = RequestMethod.POST)
public String generateReport(
        Model model,
        @Valid @ModelAttribute("reportProperties") ReportProperties reportProperties,
        BindingResult result, HttpServletResponse response) {
    if (result.hasErrors()) {
        model.addAttribute("logMessage",
                "Generowanie Raportu nie powiodlo sie.");
        return "import";
    }

    //Walidacja dat. Mozna przeniesc na validator
    if(reportProperties.getEndDate().compareTo(reportProperties.getStartDate()) < 0){
        model.addAttribute("logMessage", "Data końcowa jest wcześniejsza od poprzedniej");
        return "import";
    }

    XSSFWorkbook report = null;
    if (reportProperties.getReportType().equalsIgnoreCase("tv")) {
        report = tvReportGenerator.generate(reportProperties);
    } else if (reportProperties.getReportType().equalsIgnoreCase("prod")) {
        report = prodReportGenerator.generate(reportProperties);
    } else {
        report = totalReportGenerator.generate(reportProperties);
    }
    if (report != null) {
        saveReportOnHardDrive(report);
        sendReportToUser(report, response);
    } else {
        model.addAttribute("logMessage",
                "Generowanie Raportu nie powiodlo sie.");
    }
    return "import";
}

private void saveReportOnHardDrive(XSSFWorkbook report) {
    try {
        Resource resource = new ClassPathResource("/general.properties");
        Properties props = PropertiesLoaderUtils.loadProperties(resource);
        String path = props.getProperty("saveFilePath");
        FileOutputStream out = new FileOutputStream(new File(path
                + new Date() + ".xlsx"));
        report.write(out);
        out.close();
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

private void sendReportToUser(XSSFWorkbook report,
        HttpServletResponse response) {
    try {
        response.setContentType("application/xlsx");
        response.setHeader("Content-Disposition",
                "attachment; filename=generate.xlsx");
        report.write(response.getOutputStream());
        response.flushBuffer();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
@RequestMapping(value=“/generate”,method=RequestMethod.POST)
公共字符串生成器报告(
模型,
@有效的@ModelAttribute(“reportProperties”)reportProperties reportProperties,
BindingResult结果,HttpServletResponse){
if(result.hasErrors()){
model.addAttribute(“logMessage”,
“慷慨解囊”是一个很好的例子;
返回“导入”;
}
//Walidacja dat.Mozna przeniesc na验证器
如果(reportProperties.getEndDate().compareTo(reportProperties.getStartDate())<0){
addAttribute(“logMessage”、“Data końcowa jest wcześniejsza od poprzedniej”);
返回“导入”;
}
XSSF工作簿报告=null;
if(reportProperties.getReportType().equalsIgnoreCase(“tv”)){
report=tvReportGenerator.generate(reportProperties);
}else if(reportProperties.getReportType().equalsIgnoreCase(“prod”)){
report=prodReportGenerator.generate(reportProperties);
}否则{
report=totalReportGenerator.generate(reportProperties);
}
如果(报告!=null){
saveReportOnHardDrive(报告);
sendReportToUser(报告、响应);
}否则{
model.addAttribute(“logMessage”,
“慷慨解囊”是一个很好的例子;
}
返回“导入”;
}
专用void saveReportOnHardDrive(XSSF工作簿报告){
试一试{
资源资源=新类路径资源(“/general.properties”);
Properties props=PropertiesLoaderUtils.loadProperties(资源);
字符串路径=props.getProperty(“saveFilePath”);
FileOutputStream out=新的FileOutputStream(新文件(路径
+新日期()+“.xlsx”);
报告。写(出);
out.close();
}捕获(FileNotFoundException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}捕获(IOE1异常){
//TODO自动生成的捕捉块
e1.printStackTrace();
}
}
专用void sendReportToUser(XSSFWorkbook报表,
HttpServletResponse(响应){
试一试{
response.setContentType(“应用程序/xlsx”);
response.setHeader(“内容处置”,
“附件;文件名=generate.xlsx”);
report.write(response.getOutputStream());
response.flushBuffer();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
我尝试了一些关闭和刷新响应OutputStream的解决方案,但没有成功。 这是我的import.jsp文件:

<body>

<div id="Container">

<h1>Mediaplany GigaShopping <a href="/GigaShopping/resources/szablony/Instrukcja.pdf" target="_blank">instrukcja</a></h1>

<h2>Import Mediaplanu   <a href="/GigaShopping/resources/szablony/MediaplanSzablon.xlsx">pobierz szablon</a></h2>

<form method="POST" enctype="multipart/form-data"
    action="/GigaShopping/importMediaplan">
            <input type="file" name="mediaplanFile"/>
            <input type="submit" value="Prześlij plik"/>
</form>

<h2>Import cennika <a href="/GigaShopping/resources/szablony/CennikSzablon.xlsx" >pobierz szablon</a><a href="/GigaShopping/pricelist" style="margin-right: 4px;">aktualny cennik</a></h2>

<form method="POST" enctype="multipart/form-data"
    action="/GigaShopping/importPriceList"> 
    <input type="file" name="pricelistFile">
    <input type="submit" value="Prześlij plik">
</form>

<h2>Generowanie raportów</h2>

<form:form method="POST" action="/GigaShopping/generate" commandName="reportProperties">
    <table>
        <tr>
            <td>Typ raportu:</td>
            <td>
                <label><form:radiobutton path="reportType" value="tv"/> M/S TV</label>
                <label><form:radiobutton path="reportType" value="prod"/> M/S PROD</label>
                <label><form:radiobutton path="reportType" value="total"/> M/S TOTAL</label>
            </td>
        </tr>
        <tr>
            <td>Stacja</td>
            <td>
                <form:select path="tvName">
                    <form:options items="${televisionsList}"/>
                </form:select>
            </td>
        </tr>
        <tr>
            <td>Od</td>
            <td><form:input type="date" path="startDate" id="startDatePicker"/></td>
        </tr>   
        <tr>
            <td>Do</td>
            <td><form:input type="date" path="endDate" id="endDatePicker"/></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Generuj"></td>
        </tr>
    </table>
</form:form>

<form:form method="POST" action="/GigaShopping/requestDBContent" commandName="requestProperties">
    <form:input type="date" id="requestDatePicker" path="date"/>
    <form:select path="tvName">
        <form:option value="wszystkie">--wszystkie--</form:option>
        <form:options items="${televisionsList}"/>
    </form:select>      
    <input value="zobacz mediaplan" type="submit" name="requestMediaplanButton" />
    <input value="zobacz zamówienia" type="submit" name="requestOrdersButton"/>                     
</form:form>

<span class="logMessage">${logMessage}</span>

<footer>
    <a href="http://cns.com.pl">CNS 2015</a>
</footer>

</div>

Mediaplany GigaShopping
导入Mediaplanu
进口森尼卡
拉波托瓦酒店
典型拉波尔图:
M/S电视
M/S产品
M/S总计
斯塔恰
Od
做
--wszystkie--
${logMessage}

谢谢你的帮助。 当做 塞巴蒂安

正如@M.Deinum所说


您必须返回
null
而不是您尝试转发的页面名称。

不是再现问题的最短代码。请添加stacktrace。您不能将文件发送到客户端,然后再转发到页面,写入文件后,yu必须
返回null
而不是
返回导入
。对不起,我忘记添加stacktrace,但M.Deinum解决了这个问题。非常感谢你!