前台显示文件名乱码问题

背景:前台通过接口http://..../downloadApk?apkName=保存测试.apk 请求,后端查询数据库后显示相应的文件下载。在前端页面上下载时文件名总是错误。页面显示如下:

前台显示文件名乱码问题

原代码如下:

@ResponseBody
@RequestMapping("/downloadApk")
public R downloadApk(HttpServletRequest request,HttpServletResponse response){
    String apkN = request.getParameter("apkName");
    String apkName = apkN;
    System.out.println("css apkName:" + apkName);
    String agent = request.getHeader("USER-AGENT");

    String suffix = apkN.substring(apkN.indexOf("."), apkN.length());
    if(!suffix.equals(".apk")){
        //参数错误
        return R.error("apk名应以.apk结尾!");
    }
    String apkFilePath = applyInfoService.queryApkFile(apkN);
    System.out.println("css"+apkFilePath);
    if(com.ideal.microservice.common.util.StringUtils.empty(apkFilePath)){
        return R.error("该apk不存在,请确定apk名无误后反馈给管理员!");
    }
    //return R.ok().put("file",file);
    //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
    response.setContentType("multipart/form-data");
    //response.setContentType("text/html;charset=gbk");
    //2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)
    response.setHeader("Content-Disposition", "attachment;fileName="+apkName);
    ServletOutputStream out;
    //通过文件路径获得File对象()
    File file = new File(apkFilePath);
    try {
        FileInputStream inputStream = new FileInputStream(file);
        //3.通过response获取ServletOutputStream对象(out)
        out = response.getOutputStream();
        int b = 0;
        byte[] buffer = new byte[512];
        while (b != -1){
            b = inputStream.read(buffer);
            //4.写到输出流(out)中
            out.write(buffer,0,b);
        }
        inputStream.close();
        out.close();
        out.flush();

    } catch (IOException e) {
        e.printStackTrace();
    }
    return R.ok();
}
其中R是一个封装的用于返回的类,代码的问题之处在与
response.setHeader("Content-Disposition", "attachment;fileName="+apkName);

这句话,我们需要对apkName进行格式方面的处理。代码如下:

//获取浏览器信息
String agent = request.getHeader("USER-AGENT");

if ((agent != null) && (-1 != agent.indexOf("MSIE"))) {//ie11之前的浏览器
    apkName = URLEncoder.encode(apkName, "UTF-8");
    apkName = StringUtils.replace(apkName, "+", "%20");
    if (apkName.length() > 150) {
        apkName = new String(apkName.getBytes("GB2312"), "ISO8859-1");
        apkName = StringUtils.replace(apkName, " ", "%20");
    }
}
if ((agent != null) && (-1 != agent.indexOf("Mozilla"))) {//谷歌、火狐、
    apkName = new String(apkName.getBytes("UTF-8"), "ISO8859-1");
}