下载文件(非文件夹,非多个)(SpringBoot Mybatis-Plus)

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();
    }

}

posted @ 2021-05-10 16:02  Ideaway  阅读(135)  评论(0)    收藏  举报