package com.biddingportal.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.biddingportal.model.annextem.query.AnnexItemQuery;
import com.biddingportal.model.attachme.query.AttachmeQuery;
import com.biddingportal.model.commons.Result;
import com.biddingportal.service.AttachmeFeignClinent;
import feign.Response;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@RestController
@CrossOrigin(origins = "*",maxAge = 3600) //解决跨域
@RequestMapping("/attachmeController")
public class AttachmeController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AttachmeFeignClinent attachmeFeignClinent;
/*附件文件上传
*
* */
@PostMapping(value = "/multifileUpload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result upload(@RequestParam("file") MultipartFile file ,
@RequestParam("projectId") String projectId,
@RequestParam("user" ) String user) throws Throwable {
//通过远程访问,访问bidding系统
String result = attachmeFeignClinent.upload(file,projectId,user);
//把json字符串转化成javabean对象
Result resultObj = JSONObject.parseObject(result,Result.class);
//输入日志
logger.info("上传附件成功");
//返回结果
return resultObj;
}
/*
* 附件文件下载,这里需要返回ResponseEntity对象,而feignClient是通过Response
来接收服务提供者方返回的文件
* */
@PostMapping("/downloadAttachem")
public ResponseEntity downloadAttachme(@RequestBody AttachmeQuery attachmeQuery) throws Throwable {
//获取附件文件id
String attachmeId = attachmeQuery.getAttachmeId();
//获取附件文件名
String filename = attachmeQuery.getFileName();
logger.info("使用feign调用服务 文件下载");
ResponseEntity result = null;
InputStream inputStream = null;
try {
// feign文件下载
Response response = attachmeFeignClinent.downloadAttachme(attachmeId);
Response.Body body = response.body();
inputStream = body.asInputStream();
//创建字节数组,由于存放附件
byte[] b = new byte[inputStream.available()];
//输入流读取字节数组
inputStream.read(b);
/*设置响应头
1.设置CONTENT_DISPOSITION
2.设置CONTENT_TYPE
* */
HttpHeaders heads = new HttpHeaders();
heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename="+filename);
heads.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
result = new ResponseEntity(b, heads, HttpStatus.OK);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
logger.info("附件文件下载成功");
return result;
}
}
feginClient端
package com.biddingportal.service;
import com.biddingportal.service.impl.AttachmeFeignClinentImpl;
import feign.Response;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@FeignClient(name = "bidding",fallback = AttachmeFeignClinentImpl.class)
public interface AttachmeFeignClinent {
/*
* 附件上传保存
* */
@PostMapping(value = "/attachmeController/multifileUpload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String upload(@RequestPart("file") MultipartFile file,
@RequestParam("projectId") String projectId,
@RequestParam("user" ) String user)throws Throwable;
/*
* 附件下载
* 通过Response来接收文件流
* */
@PostMapping("/attachmeController/downloadAttachem")
Response downloadAttachme(@RequestBody String attachemId) throws Throwable;
}
//FeignClinentImpl类
package com.biddingportal.service.impl;
import com.biddingportal.service.AttachmeFeignClinent;
import feign.Response;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@Component
public class AttachmeFeignClinentImpl implements AttachmeFeignClinent {
@Override
public String upload(MultipartFile file, String projectId,String user) throws Throwable {
return "请求超时";
}
@Override
public Response downloadAttachme(String attachemId) throws Throwable {
return null;
}
}
在文件上传时FeignClient调用接口时不支持上传文件,需要设置文件编码,之前用的@Configuration 可以实现,但对于全局的请求都会影响
package com.biddingportal.config;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
/**
* feign多媒体文件传输
*/
@Configuration
public class FeignMultipartSupportConfig {
@Autowired
private ObjectFactory messageConverters;
@Bean
@Primary//自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Scope("prototype")//使用多例每次获得bean都会生成一个新的对象
public Encoder multipartFormEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
}
公共类Result.统一用于返回结果
package com.biddingportal.model.commons;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* 自定义响应结构
*/
public class Result {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态 200-成功 500-失败 404-找不到资源等.
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
public static Result build(Integer status, String msg, Object data) {
return new Result(status, msg, data);
}
public static Result ok(Object data) {
return new Result(data);
}
public static Result ok() {
return new Result(null);
}
public Result() {
}
public static Result build(Integer status, String msg) {
return new Result(status, msg, null);
}
public Result(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public Result(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
// public Boolean isOK() {
// return this.status == 200;
// }
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
* 将json结果集转化为Result对象
*
* @param jsonData json数据
* @param clazz Result中的object类型
* @return
*/
public static Result formatToPojo(String jsonData, Class> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, Result.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/**
* 没有object对象的转化
*
* @param json
* @return
*/
public static Result format(String json) {
try {
return MAPPER.readValue(json, Result.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Object是集合转化
*
* @param jsonData json数据
* @param clazz 集合中的类型
* @return
*/
public static Result formatToList(String jsonData, Class> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
}
package com.bidding.controller;
import com.bidding.model.annextem.query.AnnexItemQuery;
import com.bidding.model.annextem.vo.AnnexItemVo;
import com.bidding.model.attachme.query.AttachmeQuery;
import com.bidding.model.attachme.vo.AttachmeVo;
import com.bidding.model.commons.Result;
import com.bidding.service.AnnexItemService;
import com.bidding.service.AttachmeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@RestController
@CrossOrigin(origins = "*",maxAge = 3600) //解决跨域
@RequestMapping("/attachmeController")
public class AttachmeController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AttachmeService attachmeService;
@Autowired
private AnnexItemService annexItemService;
/**
* @param file
* @param projectId
* @return
* @throws
*/
@PostMapping(value = "/multifileUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result upload(@RequestPart("file") MultipartFile file,
@RequestParam("projectId") String projectId,
@RequestParam("user" ) String user) throws Throwable {
AttachmeQuery attachmeQuery = new AttachmeQuery();
//获取项目根目录
File genPath = null;
{
try {
genPath = new File(ResourceUtils.getURL("classpath:").getPath());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Result result = new Result();
//设置附件文件保存目录
String uploadPath =genPath + "/static/file/"+projectId +"/";
logger.info(uploadPath);
//判断附件文件是否为空
if (Objects.isNull(file) || file.isEmpty()) {
logger.error("文件为空");
return result.build(500,"对象为空");
}
try {
byte[] bytes = file.getBytes();
Path path = Paths.get(uploadPath + file.getOriginalFilename());
//如果没有files文件夹,则创建
if (!Files.isWritable(path)) {
Files.createDirectories(Paths.get(uploadPath));
}
//文件写入指定路径
Files.write(path, bytes);
logger.debug("文件写入成功");
} catch (IOException e) {
e.printStackTrace();
return result.build(500,"后端异常");
}
//附件文件id
String attachmeId = UUID.randomUUID().toString().replaceAll("-", "");
//附件文件保存路径
String path = uploadPath;
String fileName = file.getOriginalFilename();
///附件大小计算转换
String fsize = null;
int size = (int) file.getSize();
if(size>1048576){
fsize = String.valueOf(size/1048576)+"M";
}else if (size<1024){
fsize = String.valueOf(size)+"B";
}else {
fsize = String.valueOf(size/1024)+"KB";
}
logger.info(fileName + "-->" + size);
String fileType = file.getContentType(); //获取文件类型
attachmeQuery.setAttachmeId(attachmeId);
attachmeQuery.setFileUrl(path);
attachmeQuery.setFileName(fileName);
attachmeQuery.setFileType(fileType);
attachmeQuery.setFileSize(fsize);
attachmeQuery.setUploadingPeople(user);
attachmeQuery.setUploadTime(new Date());
//保存附件文件数据库记录
Result r = attachmeService.saveAttachme(attachmeQuery);
logger.info("附件文件记录已保存到数据库");
Result result1 = new Result();
if(r.getStatus() == 200){
AnnexItemQuery annexItemQuery = new AnnexItemQuery();
annexItemQuery.setRelevanceCorrelationId(projectId);
annexItemQuery.setAttachmeId(attachmeId);
result1 = annexItemService.saveAnnexItem(annexItemQuery);
logger.info("附件文件关联记录已保存");
}
return result1.build(200,"添加成功");
}
}
参考的博客链接:
文件上传:https://blog.csdn.net/jasnet_u/article/details/82805073
文件下载:https://www.2cto.com/kf/201902/797188.html