Java Web——文件下载getResourceAsStream()返回NULL解决方案
Posted Starzkg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Web——文件下载getResourceAsStream()返回NULL解决方案相关的知识,希望对你有一定的参考价值。
问题描述
严重: Servlet.service() for servlet [club.zstuca.demo.DownloadDemo] in context with path [/DEMOWeb] threw exception
java.lang.NullPointerException
at club.zstuca.demo.DownloadDemo.doGet(DownloadDemo.java:48)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
问题分析
文件不在WebAPP根目录下,导致找不到资源。
API
Class.getResourceAsStream(String path)
JDK设置这样的规则,是很好理解的,path不以“/”开头时,我们就能获取与当前类所在的路径相同的资源文件,而以“/”开头时可以获取classPath根下任意路径的资源。
path不以“/”开头时,默认是从当前类所在的包下面获取资源
path以“/”开头时,则是从项目的classPath根下获取资源
ClassLoader.getResourceAsStream(String path)
默认是从classpath根下获取,path不能以“/”开头,path是指类加载器的加载范围,在资源加载的过程中,使用逐级向上的委托的形式加载的,“/”表示Boot ClassLoader中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。
ServletContext.getResourceAsStream(String path)
默认从WebAPP根目录下取资源,Tomcat下path是否以“/”开头无所谓,当然这和具体的容器实现有关。
解决方案
1、在WebAPP根目录下创建res文件夹,将资源移入此文件夹
2、修改代码
源代码
package club.zstuca.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DownloadDemo
*/
@WebServlet("/DownloadDemo")
public class DownloadDemo extends HttpServlet
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public DownloadDemo()
super();
// TODO Auto-generated constructor stub
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
// TODO Auto-generated method stub
request.setCharacterEncoding("UTF-8");
//response.setContentType("application/octet-stream");
response.addHeader("content-Type", "application/octet-stream" );
String filename = request.getParameter("filename");
response.addHeader("content-Disposition", "attachment; filename=" + filename);
//response.getWriter().append("Served at: ").append(request.getContextPath());
InputStream in = this.getServletContext().getResourceAsStream("/res/" + filename);
System.out.println("res/" + filename);
System.out.println(in);
ServletOutputStream out = response.getOutputStream();
byte[] bs = new byte[1024];
int len = -1;
while((len=in.read(bs))!=-1)
out.write(bs,0,len);
out.close();
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
// TODO Auto-generated method stub
doGet(request, response);
参考文章
http://www.imooc.com/wenda/detail/593313
https://www.cnblogs.com/lebo0425/p/6607804.html
以上是关于Java Web——文件下载getResourceAsStream()返回NULL解决方案的主要内容,如果未能解决你的问题,请参考以下文章
[Java开发之路](18)关于Class.getResource和ClassLoader.getResource的路径问题
Java中getClassLoader().getResource()和getResource()的区别
Java:使用getClassLoader.getResource时只能用绝对路径从classpath开始找文件吗?
java程序,new ImageIcon(getClass().getResource("/images/密码登陆.jpg")),在导出jar后,jar包里面没有