问题:
报错提示
11-Apr-2024 15:38:43.792 信息 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[G:\开发工作用软件\Java开发用\apache-tomcat-10.1.7\webapps\manager]的部署已在[293]毫秒内完成
11-Apr-2024 15:38:44.573 信息 [http-nio-8080-exec-4] org.springframework.web.servlet.FrameworkServlet.initServletBean Completed initialization in 1841 ms
11-Apr-2024 15:38:45.814 警告 [http-nio-8080-exec-5] org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: com.itbaizhan.controller.fileUploadAndDownload.FileDownload
11-Apr-2024 15:38:45.834 警告 [http-nio-8080-exec-5] org.apache.coyote.http11.Http11Processor.prepareResponse HTTP响应头信息[Content-Disposition] 值[attachment;filename=XML技术.png],由于无效已从响应中移除
java.lang.IllegalArgumentException: 代码点[25,216]处的Unicode字符[技]无法编码,因为它超出了允许的0到255范围。
at org.apache.tomcat.util.buf.MessageBytes.toBytesSimple(MessageBytes.java:290)
at org.apache.tomcat.util.buf.MessageBytes.toBytes(MessageBytes.java:261)
at org.apache.coyote.http11.Http11OutputBuffer.write(Http11OutputBuffer.java:389)
at org.apache.coyote.http11.Http11OutputBuffer.sendHeader(Http11OutputBuffer.java:368)
at org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1049)
at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:376)
at org.apache.coyote.Response.action(Response.java:208)
at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:187)
at org.apache.coyote.Response.doWrite(Response.java:613)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:334)
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:750)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:677)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:382)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:360)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
at com.itbaizhan.controller.fileUploadAndDownload.FileDownload.getFile(FileDownload.java:46)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
原因:
通常windows操作系统默认采用GBK编码、浏览器请求和响应默认采用utf-8编码、Tomcat服务器内部默认iso-8859-1编码
浏览器处理响应时会默认将响应从iso-8859-1编码格式转换为utf-8编码格式
前端代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>可下载文件</title>
</head>
<body>
<h1>请选择所需下载的文件</h1>
<c:forEach items="${requestScope.fileList}" var="file">
<a href="/file/getFile?fileName=${file}">${file}</a><br>
</c:forEach>
</body>
</html>
修正前后端代码
package com.itbaizhan.controller.fileUploadAndDownload;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Controller
@RequestMapping("/file")
public class FileDownload {
//查询所有可下载文件
@RequestMapping("/findFile")
public String findFile(Model model){
//1.获取可下载文件的路径集合。。注:跨服务器上传中,网络路径无法获取文件列表。
String realPath = "H:\\myWorkspace\\springmvc\\mvc_demo1\\src\\main\\webapp\\img";
File file = new File(realPath);
String[] fileList = file.list();
// 2.将路径集合放入Model中,跳转到JSP页面
model.addAttribute("fileList",fileList);
return "downloadableFiles";
}
//下载文件
@RequestMapping("/getFile")
public void getFile(HttpServletResponse response,String fileName) throws IOException {
//设置响应头为文件下载
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//获取文件路径
String path = "H:\\myWorkspace\\springmvc\\mvc_demo1\\src\\main\\webapp\\img";
File file = new File(path,fileName);
//响应字符输出流
ServletOutputStream os = response.getOutputStream();
os.write(FileUtils.readFileToByteArray(file));
os.flush();
os.close();
}
}
修正后后端代码
package com.itbaizhan.controller.fileUploadAndDownload;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Controller
@RequestMapping("/file")
public class FileDownload {
//查询所有可下载文件
@RequestMapping("/findFile")
public String findFile(Model model){
//1.获取可下载文件的路径集合。。注:跨服务器上传中,网络路径无法获取文件列表。
String realPath = "H:\\myWorkspace\\springmvc\\mvc_demo1\\src\\main\\webapp\\img";
File file = new File(realPath);
String[] fileList = file.list();
// 2.将路径集合放入Model中,跳转到JSP页面
model.addAttribute("fileList",fileList);
return "downloadableFiles";
}
//下载文件
@RequestMapping("/getFile")
public void getFile(HttpServletResponse response,String fileName) throws IOException {
//设置响应头为文件下载
//将请求的UTF-8编码格式中文文件名转为iso-8859-1编码格式
response.setHeader("Content-Disposition","attachment;filename="+
new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
//获取文件路径
String path = "H:\\myWorkspace\\springmvc\\mvc_demo1\\src\\main\\webapp\\img";
File file = new File(path,fileName);
//响应字符输出流
ServletOutputStream os = response.getOutputStream();
os.write(FileUtils.readFileToByteArray(file));
os.flush();
os.close();
}
}