- 接口通用返回类
public enum ResponseCode { // 系统模块 SUCCESS(0, "操作成功"), ERROR(1, "操作失败"), SERVER_ERROR(500, "服务器异常"), // 通用模块 1xxxx ILLEGAL_ARGUMENT(10000, "参数不合法"), REPETITIVE_OPERATION(10001, "请勿重复操作"), ACCESS_LIMIT(10002, "请求太频繁, 请稍后再试"), MAIL_SEND_SUCCESS(10003, "邮件发送成功"), // 用户模块 2xxxx NEED_LOGIN(20001, "登录失效"), USERNAME_OR_PASSWORD_EMPTY(20002, "用户名或密码不能为空"), USERNAME_OR_PASSWORD_WRONG(20003, "用户名或密码错误"), USER_NOT_EXISTS(20004, "用户不存在"), WRONG_PASSWORD(20005, "密码错误"), // 文件模块 3xxxx FILE_EMPTY(30001,"文件不能空"), FILE_NAME_EMPTY(30002,"文件名称不能为空"), FILE_MAX_SIZE(30003,"文件大小超出"), ; ResponseCode(Integer code, String msg) { this.code = code; this.msg = msg; } private Integer code; private String msg; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
- 返回体
@Data @AllArgsConstructor @NoArgsConstructor public class Result { private int code; private String message; private Object data; }
- 配置跨域
public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") .maxAge(3600) .allowCredentials(true); } }
- 表
CREATE TABLE `file` ( `id` int(11) NOT NULL AUTO_INCREMENT, `filePath` varchar(255) DEFAULT NULL, `fileName` varchar(255) DEFAULT NULL, `fileSuffix` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
- 实体类
@Data @AllArgsConstructor @NoArgsConstructor @Getter @Setter @EqualsAndHashCode public class Files implements Serializable { private static final long serialVersionUID=1L; /** * 文件存储路径 */ private String filePath; /** * 文件名称 */ private String fileName; /** * 文件后缀名 */ private String fileSuffix; }
- Controller
@RestController @RequestMapping("/api") public class FileController { @Autowired private FileService fileService; // MultipartFile用来接收前台传过来的文件 @RequestMapping(value = "/upload",method = RequestMethod.POST) public Result upLoadFiles(MultipartFile multipartFile){ if (multipartFile.isEmpty()){ return new Result(ResponseCode.FILE_EMPTY.getCode(),ResponseCode.FILE_EMPTY.getMsg(),null); } return fileService.upLoadFiles(multipartFile); } @RequestMapping(value = "/download/{id}",method = RequestMethod.GET) public void downloadFiles(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response){ OutputStream outputStream=null; InputStream inputStream=null; BufferedInputStream bufferedInputStream=null; byte[] bytes=new byte[1024]; Files files = fileService.getFileById(id); String fileName = files.getFileName(); // 获取输出流 try { response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); response.setContentType("application/force-download"); inputStream=fileService.getFileInputStream(files); bufferedInputStream=new BufferedInputStream(inputStream); outputStream = response.getOutputStream(); int i=bufferedInputStream.read(bytes); while (i!=-1){ outputStream.write(bytes,0,i); i=bufferedInputStream.read(bytes); } } catch (IOException e) { e.printStackTrace(); }finally { try { if (inputStream!=null){ inputStream.close(); } if (outputStream!=null){ outputStream.close(); } if (bufferedInputStream!=null){ bufferedInputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
- service
public interface FileService { /** * 文件上传接口 * @param file * @return */ Result upLoadFiles(MultipartFile file); /** * 根据id获取文件 * @param id * @return */ Files getFileById(String id); /** * 根据id获取数据流 * @param files * @return */ InputStream getFileInputStream(Files files); }
@Service public class FileServiceImpl implements FileService { @Value("${file.save-path}") private String savePath; @Autowired private FileMapper fileMapper; @Override public Result upLoadFiles(MultipartFile file) { //设置支持最大上传的文件,这里是1024*1024*2=2M long MAX_SIZE=2097152L; //获取要上传文件的名称 String fileName=file.getOriginalFilename(); //如果名称为空,返回一个文件名为空的错误 if (StringUtils.isEmpty(fileName)){ return new Result(ResponseCode.FILE_NAME_EMPTY.getCode(),ResponseCode.FILE_NAME_EMPTY.getMsg(),null); } //如果文件超过最大值,返回超出可上传最大值的错误 if (file.getSize()>MAX_SIZE){ return new Result(ResponseCode.FILE_MAX_SIZE.getCode(),ResponseCode.FILE_MAX_SIZE.getMsg(),null); } //获取到后缀名 String suffixName = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf(".")) : null; //文件的保存重新按照时间戳命名 String newName = System.currentTimeMillis() + suffixName; File newFile=new File(savePath,newName); if (!newFile.getParentFile().exists()){ newFile.getParentFile().mkdirs(); } try { //文件写入 file.transferTo(newFile); } catch (IOException e) { e.printStackTrace(); } //将这些文件的信息写入到数据库中 Files files=new Files(newFile.getPath(),fileName,suffixName); fileMapper.insertFile(files); return new Result(ResponseCode.SUCCESS.getCode(),ResponseCode.SUCCESS.getMsg(),"数据上传成功"); } //根据id获取文件信息 @Override public Files getFileById(String id) { Files files = fileMapper.selectFileById(id); return files; } //将文件转化为InputStream @Override public InputStream getFileInputStream(Files files) { File file=new File(files.getFilePath()); try { return new FileInputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } }
- Mapper
@Mapper @Repository public interface FileMapper { /** * 将数据信息插入到数据库 * @param files */ void insertFile(Files files); /** * 根据id获取文件 * @param id * @return */ Files selectFileById(String id); }
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javayz.fileuploadanddownload.mapper.FileMapper"> <insert id="insertFile" parameterType="com.javayz.fileuploadanddownload.entity.Files"> insert into file(filepath,filename,filesuffix) values(#{filePath},#{fileName},#{fileSuffix}); </insert> <select id="selectFileById" parameterType="string" resultType="com.javayz.fileuploadanddownload.entity.Files"> select * from file where id=#{id}; </select> </mapper>