我在HttpServletResponse
标题中设置了文件名,但是当我下载它时没有这个文件名
FileInputStream fis = new FileInputStream(fileDocumento);
PortletResponse portletResponse=(PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse);
res.setHeader("Content-Disposition", "attachment; filename=schedaObiettivoTAC_.docx");
res.setHeader("Content-Transfer-Encoding", "binary");
res.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
res.flushBuffer();
OutputStream out=res.getOutputStream();
out.write(IOUtils.toByteArray(fis));
out.close();
fis.close();
答案 0 :(得分:1)
您不应使用HttpServletResponse
。相反,您应该创建自定义Resource
和ResourceHandler
:
CustomResourceHandler.java
:
public final class CustomResourceHandler extends ResourceHandlerWrapper {
// Public Constants
public static final String LIBRARY_NAME = "exampleLib";
public static final String RESOURCE_NAME = "exampleName";
// Private Data Members
private ResourceHandler wrappedResourceHandler;
public CustomResourceHandler(ResourceHandler resourceHandler) {
this.wrappedResourceHandler = resourceHandler;
}
@Override
public Resource createResource(String resourceName, String libraryName) {
if (LIBRARY_NAME.equals(libraryName)) {
if (RESOURCE_NAME.equals(resourceName)) {
return new CustomResource(libraryName, resourceName,
"exampleFileName.txt", "Example Content");
}
else {
return super.createResource(resourceName, libraryName);
}
}
else {
return super.createResource(resourceName, libraryName);
}
}
@Override
public ResourceHandler getWrapped() {
return wrappedResourceHandler;
}
@Override
public boolean libraryExists(String libraryName) {
if (LIBRARY_NAME.equals(libraryName)) {
return true;
}
else {
return super.libraryExists(libraryName);
}
}
/* package-private */ static final class CustomResource extends Resource {
private final String content;
private final Map<String, String> responseHeaders;
private final String requestPath;
private final URL url;
public CustomResource(String libraryName, String resourceName,
String fileName, String content) {
super.setLibraryName(libraryName);
super.setResourceName(resourceName);
super.setContentType("text/plain");
Map<String, String> responseHeaders = new HashMap<String, String>();
responseHeaders.put("Content-Disposition",
"attachment; filename=" + fileName + ";");
this.responseHeaders = Collections.unmodifiableMap(responseHeaders);
StringBuilder sb = new StringBuilder();
sb.append(ResourceHandler.RESOURCE_IDENTIFIER);
sb.append("/");
sb.append(super.getResourceName());
sb.append("?ln=");
sb.append(super.getLibraryName());
this.requestPath = sb.toString();
URL url;
try {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
url = new URL(externalContext.encodeResourceURL(this.requestPath));
}
catch (MalformedURLException e) {
url = null;
}
this.url = url;
this.content = content;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(
content.getBytes(StandardCharsets.UTF_8));
}
@Override
public String getRequestPath() {
return requestPath;
}
@Override
public Map<String, String> getResponseHeaders() {
return responseHeaders;
}
@Override
public URL getURL() {
return url;
}
@Override
public boolean userAgentNeedsUpdate(FacesContext facesContext) {
// Return false if the content cannot change dynamically.
return true;
}
}
}
WEB-INF/faces-config.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<!-- ... -->
<resource-handler>custom.resource.handler.CustomResourceHandler</resource-handler>
</application>
<!-- ... -->
</faces-config>
下面是一些下载资源的示例代码:
<h:outputLink target="_blank" value="#{bean.getDownloadURL(facesContext)}">
<h:outputText value="download" />
</h:outputLink>
public String getDownloadURL(FacesContext facesContext) {
return facesContext.getApplication().getResourceHandler()
.createResource(CustomResourceHandler.RESOURCE_NAME,
CustomResourceHandler.LIBRARY_NAME)
.getURL().toString();
}
您也可以在the Liferay Faces JSF Export PDF中查看完整的portlet示例,以下载/导出文件。
答案 1 :(得分:-1)
如果您处于portlet的 action 或 render 阶段(我猜对于JSF portlet):有一个ResponseWrapper
将会抑制任何标题。我正在使用此方法来查找在JSF生命周期中发送二进制数据的响应:
public static HttpServletResponse getHttpServletResponse() {
final FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
throw new IllegalStateException("Not inside a JSF request");
}
final Object responseObject = facesContext.getExternalContext().getResponse();
if (responseObject instanceof HttpServletResponse) {
return (HttpServletResponse) responseObject;
}
if (responseObject instanceof PortletResponse) {
// Use Liferays util to find the real response
HttpServletResponse response = PortalUtil.getHttpServletResponse((PortletResponse) responseObject);
// Find the outer most response (setting the headers would have no effect, as we are included)
while (response instanceof ServletResponseWrapper) {
final ServletResponse servletResponse = ((ServletResponseWrapper) response).getResponse();
if (!(servletResponse instanceof HttpServletResponse)) {
break;
}
response = (HttpServletResponse) servletResponse;
}
return response;
}
throw new IllegalStateException("Unknown type of response object: " + responseObject);
}