本地测试时,直接上传图片到resources/static 文件下没有问题,但是打成jar后,直接报错
@RequestMapping(value = "/oldUploadImage",method = RequestMethod.POST)
public void oldUploadImage(MultipartFile image) throws IOException {
String name = image.getOriginalFilename();
InputStream inputStream = image.getInputStream();
String staticPath = ResourceUtils.getFile("classpath:static/").getAbsolutePath();
Path path = Paths.get(staticPath).resolve(UPLOAD_PATH);
if (!Files.exists(path)){
Files.createDirectories(path);
}
Files.copy(inputStream,path.resolve(name));
}
错误信息
java.io.FileNotFoundException: class path resource [static/] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/360/sell-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:180)
at com.imooc.sell.controller.image.ImageTest.oldUploadImage(ImageTest.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
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.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
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:198)
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:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
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)
这个是打成jar后就不可以再动态修改resources文件下的文件了。
解决方法:
(1)在jar外动态创建文件夹,将图片文件上传到该文件夹中,然后给springboot赋予读/写该文件夹的权限,即可使用url直接读写,或使用流将图片输出。
源码:
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @author peter
* 2018/10/20 21:32
*/
@Controller
@Slf4j
public class ImageTest {
private static String UPLOAD_PATH = "File/image/upload";
//上传图片
@RequestMapping(value = "/uploadImage", method = RequestMethod.POST)
@ResponseBody
public String uploadImage(MultipartFile image) {
try {
String name = image.getOriginalFilename();
System.out.println(name);
InputStream inputStream = image.getInputStream();
Path directory = Paths.get(UPLOAD_PATH);
if(!Files.exists(directory)){
Files.createDirectories(directory);
}
long copy = Files.copy(inputStream, directory.resolve(name));
return "上传成功,大小:"+ copy;
} catch (Exception e) {
log.error(e.getMessage(), e);
return "上传失败";
}
}
//使用流将图片输出
@GetMapping("/getImage/{name}")
public void getImage(HttpServletResponse response, @PathVariable("name")String name) throws IOException {
response.setContentType("image/jpeg;charset=utf-8");
response.setHeader("Content-Disposition", "inline; filename=girls.png");
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(Files.readAllBytes(Paths.get(UPLOAD_PATH).resolve(name)));
outputStream.flush();
outputStream.close();
}
}
(2)实现WebMvcConfigurer 重写addResourceHandlers(ResourceHandlerRegistry registry)方法,给新建的外部文件夹注册(赋予读/写权限)配置到springboot中即可
@SpringBootApplication
public class DemoApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/File/**")
.addResourceLocations("file:File/");
}
}
测试:在static 文件下新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="icon" href="favicon.ico">
</head>
<body>
<form action="http://localhost:8080/uploadImage" method="post" enctype="multipart/form-data">
<input name="image" type="file">
<input type="submit" value="提交">
</form>
</body>
</html>
1、本地测试
http://localhost:8080/index.html
上传图片后,发现在springboot项目下多出一个File文件夹
输入
http://localhost:9000/sell/getImage/ss.jpg
或
http://localhost:8080/File/image/upload/ss.jpg
都可看到图片
2、打包后测试
mvn package
java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8080
输入上述地址依然可看图片,只不过新创建的文件夹在jar包的同目录下创建