springboot打成jar后獲取classpath下文件
代碼如下:
1
2
3
|
ClassPathResource resource = new ClassPathResource( "app.keystore" ); File file = resource.getFile(); FileUtils.readLines(file).forEach(System.out::println); |
解決方式如下:
1. Spring framework
1
2
3
4
5
6
7
8
|
String data = "" ; ClassPathResource cpr = new ClassPathResource( "static/file.txt" ); try { byte [] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream()); data = new String(bdata, StandardCharsets.UTF_8); } catch (IOException e) { LOG.warn( "IOException" , e); } |
2.use a file
1
2
3
4
5
6
7
8
|
ClassPathResource classPathResource = new ClassPathResource( "static/something.txt" ); InputStream inputStream = classPathResource.getInputStream(); File somethingFile = File.createTempFile( "test" , ".txt" ); try { FileUtils.copyInputStreamToFile(inputStream, somethingFile); } finally { IOUtils.closeQuietly(inputStream); } |
1
2
3
|
Resource resource = new ClassPathResource( "data.sql" ); BufferedReader reader = new BufferedReader( new InputStreamReader(resource.getInputStream())); reader.lines().forEach(System.out::println); |
1
|
String content = new ClassPathResourceReader( "data.sql" ).getContent(); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Value ( "${resourceLoader.file.location}" ) @Setter private String location; private final ResourceLoader resourceLoader; public void readallfilesfromresources() { Resource[] resources; try { resources = ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources( "classpath:" + location + "/*.json" ); for ( int i = 0 ; i < resources.length; i++) { try { InputStream is = resources[i].getInputStream(); byte [] encoded = IOUtils.toByteArray(is); String content = new String(encoded, Charset.forName( "UTF-8" )); } } } catch (IOException e) { throw new UncheckedIOException(e); } } |
springboot-項目獲取resources下文件碰到的問題(classPath下找不到文件和文件名亂碼)
項目是spring-boot + spring-cloud 并使用maven 管理依賴。在springboot+maven項目下怎么讀取resources下的文件實現文件下載?
怎么獲取resources目錄下的文件?(相對路徑)
方法一:
1
|
File sourceFile = ResourceUtils.getFile( "classpath:templateFile/test.xlsx" ); //這種方法在linux下無法工作 |
方法二:
1
|
Resource resource = new ClassPathResource( "templateFile/test.xlsx" ); File sourceFile = resource.getFile(); |
我使用的是第二種。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
@PostMapping ( "/downloadTemplateFile" ) public JSONData downloadTemplateFile(HttpServletResponse response) { String filePath = "templateFile/test.xlsx" ; Resource resource = new ClassPathResource(filePath); //用來讀取resources下的文件 InputStream is = null ; BufferedInputStream bis = null ; OutputStream os = null ; try { File file = resource.getFile(); if (!file.exists()) { return new JSONData( false , "模板文件不存在" ); } is = new FileInputStream(file); os = response.getOutputStream(); bis = new BufferedInputStream(is); //設置響應頭信息 response.setCharacterEncoding( "UTF-8" ); this .response.setContentType( "application/octet-stream; charset=UTF-8" ); StringBuffer contentDisposition = new StringBuffer( "attachment; filename=\"" ); String fileName = new String(file.getName().getBytes(), "utf-8" ); contentDisposition.append(fileName).append( "\"" ); this .response.setHeader( "Content-disposition" , contentDisposition.toString()); //邊讀邊寫 byte [] buffer = new byte [ 500 ]; int i; while ((i = bis.read(buffer)) != - 1 ) { os.write(buffer, 0 , i); } os.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); return new JSONData( false , "模板文件不存在" ); } catch (IOException e) { e.printStackTrace(); } finally { try { if (os != null ) os.close(); if (bis != null ) bis.close(); if (is != null ) is.close(); } catch (IOException e) { e.printStackTrace(); } } return new JSONData( "模板文件下載成功" ); } |
高高興興的啟動項目后發現還是找不到文件,錯誤日志:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
java.io.FileNotFoundException: class path resource [templateFile/test.xlsx] cannot be resolved to URL because it does not exist at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java: 195 ) at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java: 129 ) at com.citycloud.parking.support.controller.operate.OperateBusinessUserController.downloadTemplateFile(OperateBusinessUserController.java: 215 ) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 62 ) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java: 43 ) at java.lang.reflect.Method.invoke(Method.java: 498 ) 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.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java: 158 ) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java: 126 ) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java: 111 ) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java: 107 ) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java: 193 ) |
因為我知道Resource resource = new ClassPathResource("templateFile/test.xlsx");就是到classPath*(注意這里有個*)下去找,然后就去項目本地的目錄下找classPath下是否有這個文件(maven的classPath在 “target\classes”目錄下),就發現并沒有這個文件在。
后面仔細想想這是Maven項目啊,所以就找pom.xml文件去看看,突然想起:springboot的maven默認只會加載classPath同級目錄下文件(配置那些),其他的需要配置<resources>標簽:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
< build > < resources > < resource > < directory >src/main/java</ directory > < includes > < include >**/*.properties</ include > < include >**/*.xml</ include > </ includes > <!--是否替換資源中的屬性--> < filtering >false</ filtering > </ resource > < resource > < directory >src/main/resources</ directory > < includes > < include >**/*.properties</ include > < include >**/*.xml</ include > < include >**/*.yml</ include > < include >**/Dockerfile</ include > < include >**/*.xlsx</ include > </ includes > <!--是否替換資源中的屬性--> < filtering >false</ filtering > </ resource > </ resources > </ build > |
重新啟動,再到classPath下看,發現有了這個文件了,同時也能獲取了。如果文件名為中文的話就會出現亂碼的情況。
怎么解決文件名中文亂碼?
1
2
3
4
5
6
7
8
9
|
Access-Control-Allow-Origin →* Access-Control-Allow-Credentials → true Access-Control-Allow-Headers →accessToken,Access-Control-Allow-Origin,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers Access-Control-Allow-Methods →POST,GET,PUT,PATCH,DELETE,OPTIONS,HEAD Access-Control-Max-Age → 360 Content-disposition →attachment; filename= "????????-??????????.xlsx" Content-Type →application/octet-stream;charset=UTF- 8 Transfer-Encoding →chunked Date →Fri, 19 Apr 2019 06 : 47 : 34 GMT |
上面是使用postman測試中文亂碼response響應頭相關信息。
后面怎么改都亂碼,然后我就試著到瀏覽器中請求試試,結果發現只是postman的原因,只要文件名編碼跟返回內容編碼一致("Content-disposition"和“ContentType”)就行:
1
2
3
4
5
6
7
|
this .response.setContentType( "application/octet-stream; charset=iso-8859-1" ); StringBuffer contentDisposition = new StringBuffer( "attachment; filename=\"" ); String fileName = file.getName(); contentDisposition.append(fileName).append( "\"" ); //設置文件名編碼 String contentDispositionStr = new String(contentDisposition.toString().getBytes(), "iso-8859-1" ); this .response.setHeader( "Content-disposition" , contentDispositionStr); |
到此全部結束!
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/qq_27384769/article/details/99877083