Controller
/**
* 下载文件
*/
@GetMapping(value = "/downloadFile")
public HttpResult downloadFile(HttpServletResponse response, HttpServletRequest request) {
Boolean flag = sysSubjectService.downloadFile(response, request);
if (flag == false) {
return HttpResult.error("文件为空");
}
return null;
}
Service
@Override
public Boolean downloadFile(HttpServletResponse response, HttpServletRequest request) {
FileIOUtil fileIOUtil = new FileIOUtil();
Boolean flag = fileIOUtil.downloadFile(response, request, SysConstants.FILE_SERVICE_SUBJECT, SysConstants.FILE_SUBJECT_MOULD, sysFileMapper);
return flag;
}
FileIOUtil
public class FileIOUtil {
public Boolean downloadFile(HttpServletResponse response, HttpServletRequest request){
//getFilePath() 为获取数据库中存储的路径
String filePath = getFilePath();
File file = new File(filePath);
if (!file.exists() || file.length() == 0){
return false;
}
FileIOUtil fileDownLoadUtil = new FileIOUtil();
try {
fileDownLoadUtil.downLoad(filePath, response, request);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return true;
}
public boolean downLoad(String filePath, HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
int lastIndexOf = filePath.lastIndexOf("\");
String substring = filePath.substring(lastIndexOf + 1, filePath.length());
File file = new File(filePath);
if (!file.exists()) {
return false;
}
generate(substring, request, response);
/* 设置文件ContentType类型,这样设置,会自动判断下载文件类型 */
response.setContentType("application/force-download");
/* 设置文件头:最后一个参数是设置下载文件名 */
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
byte[] buffer = new byte[1024];
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis)) {
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
os.flush();
os.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
return true;
}
/**
* 处理文件名乱码和浏览器兼容问题
*
* @param fileName 文件名字
* @param request
* @param response
* @author 吕嘉鸣
*/
private static void generate(String fileName, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "application/octet-stream");
// response.setContentType("application/octet-stream");
// response.setHeader("success", "true");
String userAgent = request.getHeader("User-Agent");
String formFileName;
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
// 针对IE或者以IE为内核的浏览器:
formFileName = URLEncoder.encode(fileName, "UTF-8");
} else {
// 非IE浏览器的处理:
formFileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
//如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
response.setHeader("Content-Disposition", "attachment;filename=" + formFileName);
// content-disposition","attachment; filename=fname.ext
}
}
在 WebSecurityConfig 中放开下载链接的限制
WebSecurityConfig
package blog;
import cn.edu.qfnu.soft.common.security.JwtAuthenticationFilter;
import cn.edu.qfnu.soft.common.security.JwtAuthenticationProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.web.cors.CorsUtils;
import javax.annotation.Resource;
/**
* Spring Security配置
* @author gjn
*/
@Configuration
@EnableWebSecurity // 开启Spring Security
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启权限注解,如:@PreAuthorize注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// 使用自定义身份验证组件
auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf
http.cors().and().csrf().disable()
.authorizeRequests()
//处理跨域请求中的Preflight请求
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
// 跨域预检请求
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/img/**").permitAll()
// 开放下载权限 #####################################
.antMatchers("/user/downloadFile").permitAll()
// web jars
//.antMatchers("/webjars/**").permitAll()
// 查看SQL监控(druid)
//.antMatchers("/druid/**").permitAll()
// 首页和登录页面
//.antMatchers("/").permitAll()
//.antMatchers("/login").permitAll()
//.antMatchers("/loginByMoble").permitAll()
// swagger
//.antMatchers("/swagger-ui.html").permitAll()
//.antMatchers("/swagger-resources/**").permitAll()
//.antMatchers("/v2/api-docs").permitAll()
//.antMatchers("/webjars/springfox-swagger-ui/**").permitAll()
// 验证码
// .antMatchers("/captcha.jpg**").permitAll()
// 服务监控
// .antMatchers("/actuator/**").permitAll()
// websocket
// .antMatchers("/websocket/**").permitAll()
// Uniapp
//.antMatchers("/uniapp/**").permitAll()
//会签公示页面
// 其他所有请求需要身份认证
.anyRequest().authenticated();
// 退出登录处理器
http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
// token验证过滤器
http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}