1.读取jar包中resource下文件
正常我们在本地debug代码的时候,用File的方式,或者其他ResourceUtil的方式,都可以取到resource下的文件,但是打成jar包发到线上,就会报取不到文件
解决办法:
PathMatchingResourcePatternResolver
注意路径必须带
classpath*:
如果不带classpath*: 那么进行空判断时,就算这个文件不存在,ObjectUtils.isEmpty也不会返回true
以下为正确示例代码
public byte[] readFile(String cityId) throws Exception {
InputStream resourceAsStream = null;
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath*:"+cityId+"_zip_base.txt");
//如果指定城市对应的配置文件为空 那就取原型默认的
if(ObjectUtils.isEmpty(resources)){
resources = resolver.getResources("classpath*:00000_zip_base.txt");
}
if(!ObjectUtils.isEmpty(resources)){
resourceAsStream = resources[0].getInputStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = resourceAsStream.read(buffer))) {
outputStream.write(buffer, 0, n);
}
return outputStream.toByteArray();
}else{
throw new PlatRuntimeException(ErrorCodeConstant.downloadFileError, null, "文件读取出错");
}
}
补充
Thread.currentThread().getContextClassLoader("资源文件名")也可以加载资源文件 ,
参考这个博客,可以通过static代码块,在初始化时就把资源文件加载进来 CSDN
2.如何在本地测试是否能读到jar包中的文件
我开始一遍一遍的重启线上,但是这势必会影响别人使用
然后本地install一个jar包,java -jar自己调试
还有一个坑,本地jar包好用但是线上还是不好用,clean一下
3.入口和出口参数格式
@Consumes设置入口参数格式
@Produces设置出口参数格式
@Consumes("application/json;charset=UTF-8")
@Produces("application/octet-stream")
在org.springframework.http.MediaType可以看到所有类型的格式
在spring的http包下,截图只是一部分
其实,这不是sofa特有的,点开@RequestMapping注解,也有 consumes属性和produces属性
@RequestMapping(consumes={"multipart/form-data",""},produces={"application/json;charset=UTF-8"})
Map<String, Object> importZip(@RequestParam("file") MultipartFormDataInput file);
数组类型属性用大括号{}包起来,多个时候大括号中用逗号,隔开
4.返回类型
Response
在javax.ws.rs.core包下
readFile就是上边贴的第一段代码
public Response downloadZip(String cityId) {
byte[] bytes = null;
try {
bytes = zipToBase64Util.readFile(cityId);
} catch (Exception e) {
throw new PlatRuntimeException(ErrorCodeConstant.downloadFileError, null, "文件读取出错");
}
String fileName = "documentation.rar";
Response.ResponseBuilder response = Response.ok(bytes);
response.header("Content-Disposition", "attachment; filename=\""+fileName+"\"");
return response.build();
}
5.Content-Disposition
Response.setStatus()//设置状态码
Response.ok 这是状态码为200
Response.ok我存base64字节是好用的 存stream测试无法返回报类型不符合 没有测试存FIle
content-disposition:服务器告诉客户端以什么方式打开响应体数据值
In-line:默认值,在当前页面内打开
Attachment;filename=xxx;以附件形式打开响应体,文件下载
如果filename文件名带中文,需要进行utf-8编码
6.请求http类型
想要浏览器直接下载,用的Get请求
参数直接放路径上
@GET
@Produces("application/octet-stream")
@Path("/downloadZip/{cityId}")
Response downloadZip(@PathParam("cityId") String cityId);
7.追更
正常的RequestMapping接口下载
其实万变不离其中,都是要把文件流或者二进制字节码放在response中,只是RequestMapping是放在HttpServletResponse的response中
public void fileDownLoad(FileDownLoadRequest fileDownLoadRequest, HttpServletResponse response) {
FileDownLoad fileDownLoad = fileDownRepository.fileDownLoad(FileDownLoad.builder().fileId(fileDownLoadRequest.getFileId()).build());
OutputStream out = null;
try {
response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileDownLoad.getFileName().getBytes()));
out = response.getOutputStream();
out.write(fileDownLoad.getByteInput());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}