diff --git a/build.gradle b/build.gradle index 0d63e14..6684461 100644 --- a/build.gradle +++ b/build.gradle @@ -58,7 +58,9 @@ subprojects { // JSON compile("com.alibaba:fastjson:$fastjsonVersion") // Apache Commons - compile("org.apache.commons:commons-lang3:3.8.1") + compile("org.apache.commons:commons-lang3:3.8.1", + "commons-fileupload:commons-fileupload:1.3.3", + "commons-io:commons-io:2.6") // 单元测试 testCompile("org.springframework.boot:spring-boot-starter-test:$springBootVersion") diff --git a/diboot-example/build.gradle b/diboot-example/build.gradle index 9d90e3e..ad1fd18 100644 --- a/diboot-example/build.gradle +++ b/diboot-example/build.gradle @@ -6,5 +6,8 @@ dependencies { compile project(":diboot-shiro-wx-cp") compile project(":diboot-components-msg") + // 七牛 + compile ("com.qiniu:qiniu-java-sdk:7.2.7") + testCompile group: 'junit', name: 'junit', version: '4.12' } \ No newline at end of file diff --git a/diboot-example/src/main/java/com/diboot/example/config/SpringMvcConfig.java b/diboot-example/src/main/java/com/diboot/example/config/SpringMvcConfig.java index 87a7463..961f84e 100644 --- a/diboot-example/src/main/java/com/diboot/example/config/SpringMvcConfig.java +++ b/diboot-example/src/main/java/com/diboot/example/config/SpringMvcConfig.java @@ -3,6 +3,7 @@ package com.diboot.example.config; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import com.diboot.core.config.Cons; import com.diboot.core.util.D; import com.diboot.core.util.DateConverter; import org.mybatis.spring.annotation.MapperScan; @@ -10,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -17,6 +19,8 @@ import org.springframework.format.FormatterRegistry; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.ArrayList; @@ -29,13 +33,16 @@ import java.util.List; * @date 2019/1/19 */ @Configuration -@EnableAutoConfiguration +@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class}) @EnableTransactionManagement(proxyTargetClass=true) @ComponentScan(basePackages={"com.diboot"}) @MapperScan({"com.diboot.**.mapper"}) public class SpringMvcConfig implements WebMvcConfigurer{ private static final Logger log = LoggerFactory.getLogger(SpringMvcConfig.class); + //10M + private static final Long MAX_UPLOAD_SIZE = 10*1024*1024L; + /** * JSON转换组件替换为fastJson */ @@ -58,6 +65,15 @@ public class SpringMvcConfig implements WebMvcConfigurer{ return new HttpMessageConverters(httpMsgConverter); } + // 需要文件上传,开启此配置 + @Bean + public MultipartResolver multipartResolver(){ + CommonsMultipartResolver bean = new CommonsMultipartResolver(); + bean.setDefaultEncoding(Cons.CHARSET_UTF8); + bean.setMaxUploadSize(MAX_UPLOAD_SIZE); + return bean; + } + @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new DateConverter()); diff --git a/diboot-example/src/main/java/com/diboot/example/controller/FileUploadController.java b/diboot-example/src/main/java/com/diboot/example/controller/FileUploadController.java new file mode 100644 index 0000000..be79810 --- /dev/null +++ b/diboot-example/src/main/java/com/diboot/example/controller/FileUploadController.java @@ -0,0 +1,147 @@ +package com.diboot.example.controller; + +import com.diboot.core.config.BaseConfig; +import com.diboot.core.util.S; +import com.diboot.core.util.V; +import com.diboot.core.vo.JsonResult; +import com.diboot.core.vo.Status; +import com.diboot.example.util.QiniuHelper; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/upload") +public class FileUploadController { + private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class); + + private static String SAVE_PATH = BaseConfig.getProperty("files.storage.directory"); + + /* + * 单图片 + * */ + @PostMapping("/image") + public JsonResult imageUpload(@RequestParam("image") MultipartFile image, ModelMap modelMap, HttpServletRequest request){ + + String fileName = saveFile(image); + if(V.notEmpty(fileName)){ + modelMap.put("url", fileName); + modelMap.put("status", "done"); + return new JsonResult(modelMap); + } + + modelMap.put("status", "error"); + return new JsonResult(Status.FAIL_OPERATION, modelMap); + } + + /* + * 多图片 + * */ + @PostMapping("/images") + public JsonResult imagesUpload(@RequestParam("images") MultipartFile[] images, ModelMap modelMap, HttpServletRequest request){ + if(V.notEmpty(images)){ + List fileNameList = new ArrayList(); + for(MultipartFile image : images){ + String fileName = saveFile(image); + if(V.notEmpty(fileName)){ + fileNameList.add(fileName); + }else{ + logger.warn("有文件上传失败:"+image.getOriginalFilename()); + } + } + + if(V.notEmpty(fileNameList)){ + modelMap.put("url", fileNameList); + modelMap.put("status", "done"); + return new JsonResult(modelMap); + } + } + + modelMap.put("status", "error"); + return new JsonResult(Status.FAIL_OPERATION, modelMap); + } + + /* + * 单文件 + * */ + @PostMapping("/office") + public JsonResult officeUpload(@RequestParam("office") MultipartFile office, ModelMap modelMap, HttpServletRequest request){ + String fileName = saveFile(office); + if(V.notEmpty(fileName)){ + modelMap.put("url", fileName); + modelMap.put("status", "done"); + return new JsonResult(modelMap); + } + modelMap.put("status", "error"); + return new JsonResult(Status.FAIL_OPERATION, modelMap); + } + + /* + * 多文件 + * */ + @PostMapping("/offices") + public JsonResult officesUpload(@RequestParam("offices") MultipartFile[] offices, ModelMap modelMap, HttpServletRequest request){ + if(V.notEmpty(offices)){ + List fileNameList = new ArrayList(); + for(MultipartFile office : offices){ + String fileName = saveFile(office); + if(V.notEmpty(fileName)){ + fileNameList.add(fileName); + }else{ + logger.warn("有文件上传失败:"+office.getOriginalFilename()); + } + } + + if(V.notEmpty(fileNameList)){ + modelMap.put("url", fileNameList); + modelMap.put("status", "done"); + return new JsonResult(modelMap); + } + } + return new JsonResult(Status.FAIL_OPERATION, modelMap); + } + + public String saveFile(MultipartFile file){ + if(V.isEmpty(file)){ + return null; + } + String fileName = file.getOriginalFilename(); + String ext = fileName.substring(fileName.lastIndexOf(".")+1); + String newFileName = S.newUuid() + "." + ext; + String fullPath = SAVE_PATH + newFileName; + File f = new File(fullPath); + if(!f.exists()){ + try { + FileUtils.writeByteArrayToFile(f, file.getBytes()); + if(logger.isDebugEnabled()){ + logger.info("文件保存成功"); + return fullPath; + //如果上传文件到七牛,打开此注释 + /*String link = QiniuHelper.uploadFile2Qiniu(newFileName, SAVE_PATH); + if(V.notEmpty(link)){ + logger.info("文件上传七牛成功"); + return link; + }*/ + } + } catch (IOException e) { + logger.error("文件保存失败"); + e.printStackTrace(); + } + } + + return null; + } + +} diff --git a/diboot-example/src/main/java/com/diboot/example/util/QiniuHelper.java b/diboot-example/src/main/java/com/diboot/example/util/QiniuHelper.java new file mode 100644 index 0000000..1472d09 --- /dev/null +++ b/diboot-example/src/main/java/com/diboot/example/util/QiniuHelper.java @@ -0,0 +1,80 @@ +package com.diboot.example.util; + +import com.diboot.core.config.BaseConfig; +import com.diboot.core.util.S; +import com.google.gson.Gson; +import com.qiniu.common.QiniuException; +import com.qiniu.common.Zone; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.storage.model.DefaultPutRet; +import com.qiniu.util.Auth; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * @author wangyongliang + * @version 2019/7/4 + */ +public class QiniuHelper { + private static final Logger logger = LoggerFactory.getLogger(QiniuHelper.class); + + private static String accessKey = BaseConfig.getProperty("qiniu.key.access"); + private static String secretKey = BaseConfig.getProperty("qiniu.key.secret"); + private static String bucket = BaseConfig.getProperty("qiniu.bucket.name"); + private static String imageDomain = BaseConfig.getProperty("qiniu.image.domain"); + + public static String getAccessKey(){ + return accessKey; + } + public static String getSecretKey(){ + return secretKey; + } + public static String getBucket(){ + return bucket; + } + + /*** + * 上传文件到七牛 + * @param fileName + * @return + */ + public static String uploadFile2Qiniu(String fileName, String savePath){ + //构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(Zone.zone0()); + //...其他参数参考类注释 + UploadManager uploadManager = new UploadManager(cfg); + + //默认不指定key的情况下,以文件内容的hash值作为文件名 + Auth auth = Auth.create(accessKey, secretKey); + String upToken = auth.uploadToken(bucket); + String localImageFullPath = savePath+fileName; + try { + Response response = uploadManager.put(localImageFullPath, S.newUuid(), upToken); + //解析上传成功的结果 + DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); + // 返回全路径URL + if(putRet.key != null){ + //删除零时文件 + File wavFile = new File(localImageFullPath); + if(wavFile.exists()){ + wavFile.delete(); + } + return imageDomain + putRet.key; + } + } + catch (QiniuException ex) { + Response r = ex.response; + logger.error(r.toString()); + try { + logger.error(r.bodyString()); + } catch (QiniuException ex2) { + //ignore + } + } + return fileName; + } +} diff --git a/diboot-example/src/main/resources/application.properties.default b/diboot-example/src/main/resources/application.properties.default index dfbca05..52cd353 100644 --- a/diboot-example/src/main/resources/application.properties.default +++ b/diboot-example/src/main/resources/application.properties.default @@ -6,6 +6,19 @@ spring.server.protocol=org.apache.coyote.http11.Http11Nio2Protocol spring.server.redirectPort=443 spring.server.compression=on +#文件请求大小 +spring.server.MaxFileSize=10MB +spring.server.MaxRequestSize=50MB + +#文件本地存放路径 +files.storage.directory=C:/Users/wuweiqing/Downloads/upload/ + +#七牛 +qiniu.key.access=xJPWOwatadCt8ANWPaxrhj3Dj8DGIFoN9jD29SCP +qiniu.key.secret=IbWRTTXdOKoD8qdpug7Xm+rTXX2yhKuh8tfY6Ov4t1SDq/P1oT4cbREWnbgXofwt +qiniu.bucket.name=thirdparty +qiniu.image.domain=http://thirdparty.dibo.ltd/ + # spring config spring.devtools.restart.enabled=true diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/service/impl/PermissionServiceImpl.java b/diboot-shiro/src/main/java/com/diboot/shiro/service/impl/PermissionServiceImpl.java index 50773a1..df5f2e6 100644 --- a/diboot-shiro/src/main/java/com/diboot/shiro/service/impl/PermissionServiceImpl.java +++ b/diboot-shiro/src/main/java/com/diboot/shiro/service/impl/PermissionServiceImpl.java @@ -2,6 +2,7 @@ package com.diboot.shiro.service.impl; import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.*; import com.diboot.core.service.impl.BaseServiceImpl; import com.diboot.shiro.entity.Permission;