首先是shiro权限管理,要配置文件上传拦截器
//upload文件上传
filterRuleMap.put("/upload/**", “anon”);
@Configuration
public class ShiroConfig {
@Autowired
private RedisUtil redisUtil;
/**
* 先走 filter
*
* @param securityManager the security manager
* @return the shiro filter factory bean
*/
@Bean
public ShiroFilterFactoryBean factory(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager);
Map<String, Filter> filterMap = new HashMap<>();
//设置自定义的JWT过滤器
filterMap.put("jwt", new JWTFilter(redisUtil));
factoryBean.setFilters(filterMap);
Map<String, String> filterRuleMap = new HashMap<>(2);
filterRuleMap.put("/auth/**", "anon");
filterRuleMap.put("/auth/authorization", "anon");
filterRuleMap.put("/auth/authentication", "anon");
filterRuleMap.put("/goods/**", "anon");
//upload文件上传
filterRuleMap.put("/upload/**", "anon");
// filterRuleMap.put("/**", "jwt");
filterRuleMap.put("/**", "anon");
factoryBean.setFilterChainDefinitionMap(filterRuleMap);
return factoryBean;
}
/**
* 注入 securityManager
*
* @return the security manager
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置自定义 realm.
securityManager.setRealm(customRealm());
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
@Bean
public CustomRealm customRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}
/**
* 开启shiro aop注解支持. 使用代理方式; 所以需要开启代码支持;
*
* @param securityManager 安全管理器
* @return 授权Advisor
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
紧接着就是文件管理配置类,将访问的url和文件路径写上去
registry.addResourceHandler("/driver/**").addResourceLocations(“file:”+filePath+"/upload/driver/");
@Configuration
public class FileConfig extends WebMvcConfigurerAdapter {
@Value("${filePath}")
private String filePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//上传的图片在D盘下的OTA目录下,访问路径如:http://localhost:8081/OTA/d3cf0281-bb7f-40e0-ab77-406db95ccf2c.jpg
//其中OTA表示访问的前缀。"file:D:/OTA/"是文件真实的存储路径
registry.addResourceHandler("/goods/**").addResourceLocations("file:"+filePath+"/image/goods/");
registry.addResourceHandler("/driver/**").addResourceLocations("file:"+filePath+"/upload/driver/");
registry.addResourceHandler("/commodityInspection/**").addResourceLocations("file:"+filePath+"/upload/commodityInspection/");
registry.addResourceHandler("/fhhQualification/**").addResourceLocations("file:"+filePath+"/upload/fhhQualification/");
registry.addResourceHandler("/certificate/**").addResourceLocations("file:"+filePath+"/upload/certificate/");
}
}
接下来便是代码实现了,先通过文件上传通用类获取url,保存到数据库中
@RestController
@RequestMapping("/FileLibrary")
@Api(tags = "文件管理")
public class FileLibraryController extends BaseController {
@Autowired
private IFileLibraryService fileLibraryService;
@PostMapping("/uploadFile")
@ApiOperation("司机证件上传")
public Object uploadFile(Integer id, MultipartFile file) {
//文件存储位置
String filePathKeyword="/upload/driver";
//文件访问地址
String urlPathKeyword="driver";
//前缀
String filePrefix="driver";
//文件名
String filename = file.getOriginalFilename();
FileLibrary fileLibrary = new FileLibrary();
fileLibrary.setFileId(id);
fileLibrary.setType(1);
fileLibrary.setFormerName(filename);
String url = fileLibraryService.uploadFile(file, filePrefix, filePathKeyword, urlPathKeyword);
fileLibrary.setUrl(url);
return fileLibraryService.save(fileLibrary)?ResultJson.ok():ResultJson.failure(ResultCode.BAD_REQUEST);
}
@PostMapping("/editDriver")
@ApiOperation("司机证件修改")
public Object editDriver(FileLibrary fileLibrary, MultipartFile file) {
//文件存储位置
String filePathKeyword="/upload/driver";
//文件访问地址
String urlPathKeyword="driver";
//前缀
String filePrefix="driver";
//文件名
String filename = file.getOriginalFilename();
FileLibrary one = fileLibraryService.getOne(new QueryWrapper<FileLibrary>().eq("file_id", fileLibrary.getFileId()).eq("type", 1));
if (one==null) {
return ResultJson.failure(ResultCode.NOT_EXIST);
} else {
fileLibraryService.deleteFile(one.getUrl(), filePathKeyword);
}
String url = fileLibraryService.uploadFile(file, filePrefix, filePathKeyword, urlPathKeyword);
fileLibrary.setFormerName(filename);
fileLibrary.setUrl(url);
return fileLibraryService.updateById(fileLibrary)? ResultJson.ok():ResultJson.failure(ResultCode.BAD_REQUEST);
}
}
Service接口
public interface IFileLibraryService extends IService<FileLibrary> {
/**
* 删除文件
* @param file
* @param filePrefix
* @param filePathKeyword 前后不要加下划线
* @param urlPathKeyword 前后不要加下划线
* @return
* @throws Exception
*/
public String uploadFile(MultipartFile file, String filePrefix, String filePathKeyword, String urlPathKeyword);
/**
* 删除文件
* @param fileUrl
* @param filePathKeyword
* @return
*/
public String deleteFile(String fileUrl, String filePathKeyword);
}
文件上传通用实现类,用于获取文件的url和删除文件
@Service
public class FileLibraryServiceImpl extends ServiceImpl<FileLibraryMapper, FileLibrary> implements IFileLibraryService {
@Value("${filePath}")
private String filePath;
/**
* 上传文件
* 例 文件夹地址 /filePath/filePathKeyword/filePrefix_123.jpg
* url访问路径 /filePath/urlPathKeyword/filePrefix_123.jpg
* @param file
* @param filePrefix 文件名前缀
* @param filePathKeyword 文件夹名(可多个文件夹) 前后不要加下划线
* @param urlPathKeyword url指向名 前后不要加下划线
* @return
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file, String filePrefix, String filePathKeyword, String urlPathKeyword){
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).toLowerCase();
if (file.getSize() > 2000000) {
return "文件过大";
}
//文件保存路径
File files = new File(filePath +File.separator+ filePathKeyword + File.separator);
if (!files.exists()) {
files.mkdirs();
}
//文件名: 前缀 + 日期时间 + 随机数 + 文件类型
String targetName = filePrefix + "_" + System.currentTimeMillis() + (int) ((Math.random() * 9 + 1) * 100000) + suffix;
String path = files + File.separator + targetName;
try {
file.transferTo(new File(path));
} catch (IOException e) {
e.printStackTrace();
return null;
}
String url = (File.separator + urlPathKeyword+ File.separator + targetName);
return url;
}
/**
* 删除文件
* @param fileUrl
* @param filePathKeyword
* @return
*/
@Override
public String deleteFile(String fileUrl, String filePathKeyword){
if(fileUrl!=null&&!"".equals(fileUrl)){
String[] split = fileUrl.split("\\/");
try {
File f = new File(filePath+File.separator+filePathKeyword+File.separator+split[split.length-1]);
if(f.exists()){
f.delete();
return "删除成功";
}
}catch (Exception e){
e.printStackTrace();
return "删除失败";
}
}
return "删除失败";
}
}
Mapper
public interface FileLibraryMapper extends BaseMapper<FileLibrary> {
}
文件上传的实体,与数据库中相应的表字段对应
@Data
public class FileLibrary implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
private Integer id;
/**
* 文件id
*/
private Integer fileId;
/**
* 文件类型 1代表司机的证件
*/
private Integer type;
/**
* 文件原名
*/
private String formerName;
/**
* 文件地址
*/
private String url;
/**
* 数据创建时间
*/
private Date createTime;
/**
* 创建人
*/
private String createBy;
/**
* 更改时间
*/
private Date updateTime;
/**
* 更改人
*/
private String updateBy;
/**
* 备注
*/
private String remark;
public FileLibrary() {
}
}