我有一个要求,我需要从网站上下载PDF.PDF需要在代码中生成,我认为这将是freemarker和像iText这样的PDF生成框架的组合.有更好的方法吗?
但是,我的主要问题是如何允许用户通过Spring Controller下载文件?
可能重复:
是否应该在HttpServletResponse.getOutputStream()/.getWriter()上调用.close()?
我负责关闭HttpServletResponse.getOutputStream()(或getWriter()甚至输入流)还是应该将它留给容器?
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OutputStream o = response.getOutputStream();
...
o.close(); //yes/no ?
}
Run Code Online (Sandbox Code Playgroud) 我写了一个简单的servlet如下:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// [do stuff with the PrintWriter]
out.close();
}
}
Run Code Online (Sandbox Code Playgroud)
是否有必要关闭PrintWriter
出局?如果我不关闭流会对进一步影响什么?
在第15.3.2.3节中支持的处理程序方法参数和 Spring 3.0文档的返回类型,它表示可以将java.io.OutputStream或java.io.Writer指定为使用@RequestMapping注释的方法的参数,以生成响应的内容.这个值是Servlet API公开的原始OutputStream/Writer." 方法是否有责任在编写器完成之前关闭它,或者它应该保持打开状态,而其他一些Spring进程是否会关闭它?
我想HttpServletResponse
在其内容(通常是HTML)呈现之后添加cookie .
正如这里所提到的(http://osdir.com/ml/java.jasig.uportal/2005-10/msg00276.html),这里(在刷新标题后,在Java中为响应添加一个cookie?),这个可以通过缓冲响应来实现它不会被刷新并发送到客户端(因为在将报头发送到客户端之后,响应被提交,并且不再有标头,即cookie头,可以发送到客户端).
假设这是目前的目标:我认为实现这一目标的一种可能方法是使用a HttpServletResponseWrapper
,我可以覆盖它的flushBuffer()
方法并防止将header\content实际刷新到客户端:
public class BufferedHttpServletResponse extends HttpServletResponseWrapper {
public BufferedHttpServletResponse(HttpServletResponse response) {
super(response);
}
public void flushBuffer() {
}
}
Run Code Online (Sandbox Code Playgroud)
并将此缓冲响应应用于a Filter
,以使用过滤器链的其余部分:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(response);
chain.doFilter(request, bufferedResponse);
// ... create Cookie and add it to response ... response.addCookie(newCookie)
// response.flushBuffer() ?
}
Run Code Online (Sandbox Code Playgroud)
问题:上面还可以,还是完全关闭?响应的缓冲区是否会继续填充内容\标题(并且可能会重新调整大小)直到我 …
如标题中所述,提交HttpServletResponse是什么意思?
我有一些请求拦截器,扩展HandlerInterceptorAdapter
,覆盖了postHandle
方法。后处理方法采用parameter final HttpServletResponse response
。在方法主体中有一条if
语句检查if response.isCommitted()
,该语句究竟执行什么操作?
private static final String voidResponse = "null";
@Override
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
final ModelAndView modelAndView) throws IOException {
if (!response.isCommitted()) {
if (DefaultServletHttpRequestHandler.class == handler.getClass()) {
return;
}
response.setStatus(200);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
try (final Writer writer = response.getWriter()) {
writer.write(voidResponse);
}
log.info("void method called, respond with 200 and null");
response.flushBuffer();
}
}
Run Code Online (Sandbox Code Playgroud) 我正在编写一个简单的代理应用程序,并且希望映射的 url 将由我的控制器处理,但其他 url(包括错误)可以转发到另一个不同的地址。因此,如果找不到资源,我会使用Filter
而不是HandlerInterceptorAdapter
无法调用,因为某些“资源路径处理程序”会处理它。
期待
http://localhost:8090/upload.html
> Filter
> > http://localhost:8092/upload.html
http://localhost:8090/files/upload
>Controller
http://localhost:8092/files/upload
不是
http://localhost:8090/upload.html
> Filter
> > http://localhost:8092/upload.html
http://localhost:8090/files/upload
>Controller
http://localhost:8092/files/upload
或者
http://localhost:8090/upload.html
>>Interceptor
未http://localhost:8090/error
找到
http://localhost:8090/files/upload
>>Filter
http://localhost:8092/files/upload
演示
Filter
我在我的子类中设置了一个WebMvcConfigurerAdapter
.
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
private javax.servlet.Filter proxyFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("[doFilterInternal]isCommitted=" + response.isCommitted() …
Run Code Online (Sandbox Code Playgroud) 这是我在冲洗时遇到的一些例外情况ServletOutputStream
。它不会出现在每个请求中,所以我无法重现它。
java.lang.NullPointerException
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.coyote.http11.InternalOutputBuffer.flush(InternalOutputBuffer.java:119)
at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:805)
at org.apache.coyote.Response.action(Response.java:174)
at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:366)
at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:333)
at org.apache.catalina.connector.CoyoteOutputStream.flush(CoyoteOutputStream.java:101)
at darshan.HttpRequestHandler.returnResponse(HttpRequester.java:117)
Run Code Online (Sandbox Code Playgroud)
HttpRequester.java :
private void returnResponse(HttpServletResponse response , String responseStr)
{
InputStream in = null;
ServletOutputStream out = null;
try
{
in = new ByteArrayInputStream(responseStr.getBytes("UTF-8"));
response.setContentLength(responseStr.length());
out = response.getOutputStream();
byte[] outputByte = new byte[4096];
while(in.read(outputByte, 0, 4096) != -1)
{
out.write(outputByte, 0, 4096);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
in.close();
out.flush(); //<-- Exception at …
Run Code Online (Sandbox Code Playgroud) java ×6
servlets ×6
spring ×2
controller ×1
cookies ×1
download ×1
file ×1
flush ×1
httprequest ×1
jakarta-ee ×1
java-ee ×1
spring-boot ×1
spring-mvc ×1
tomcat ×1