好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

springboot打成jar后获取classpath下文件失败的解决方案

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

查看更多关于springboot打成jar后获取classpath下文件失败的解决方案的详细内容...

  阅读:63次