0

I am trying to write a controller that generates a CSV spreadsheet to save as a file.

I have written the following action and render methods

/**
 * Get the stats for the search.
 */
@ActionMapping(params={"controller=exportView","action=csv"})
public void viewInstance(ActionRequest request, ActionResponse response){
    response.setRenderParameter("controller", "exportView");
    response.setRenderParameter("action","csv");
}


@RenderMapping(params={"controller=exportView","action=csv"})
public String viewInstance(@RequestParam(value = "id", required = true) final String viewInstanceId, RenderRequest request, RenderResponse response, Model model) throws Exception {
    ApplicationContext ctx = ThreadApplicationContextHolder.getApplicationContext();

    .. do some stuff

    String filename = getFilename();

    response.setContentType("text/csv"); // go bang here

    response.addProperty(ExportViewInstanceAsCsvFileController.HEADER_CONTENT_DISPOSITION, "attachment;filename=" + filename + ExportViewInstanceAsCsvFileController.FILE_EXT);

    viewInstanceFileRenderer.renderSearchResultNodesToFile(getData(), response.getPortletOutputStream());

    return "portlet/exportView";
}

When it runs the server complains that the content type is not "text/html", so I amended the portlet.xml to have

<supports>
  <mime-type>text/html</mime-type>
  <portlet-mode>VIEW</portlet-mode>
</supports>
<supports>
  <mime-type>text/csv</mime-type>
  <portlet-mode>VIEW</portlet-mode>
</supports>

but websphere seems to be ignoring this.

When I debug and run request.getResponseContentTypes() it only has text/html in the collection. The application structure has a portlet to handle logons and then three web applications to handle various aspects of the application. I have modified the portlet in the web application that handles the spreadsheet generation, but not in the logon portlet.

My next step is to change that(the logon portlet.xml) but I am not confident it will work.

Are there any other places I can look?

4

1 回答 1

2

您需要实现ResourceServingPortlet并让您的 portlet 类实现serveResource。您可以在其中设置内容类型和其他标头,就像您在操作中尝试并呈现响应一样。只有这一次,您的 portlet 将拥有响应,而不是仅仅对它做出贡献。您需要呈现一个链接,例如指向您的资源 URL,您可以从 doView() 中的 RenderResponse 获取该链接。

端到端,您将执行以下操作:

  1. 在 doView() 中,从 RenderResponse 获取指向您的 serveResource() 方法的 ResourceURL。
  2. 渲染一个 HTML 片段,例如,“下载 CSV”超链接,其 href 是您获得的 ResourceURL。当浏览器请求它时,您的 serveResource() 方法将被调用。
  3. 设置您的标头并将您的二进制/流写入响应。

希望这可以帮助,

  • 斯科特
于 2013-06-24T11:44:07.623 回答