岳阳建设网站,开发公司物业移交物业协议,江苏网站seo,淘宝网站首页是用什么软件做的#x1f600;#x1f600;#x1f600;创作不易#xff0c;各位看官点赞收藏. 文章目录 Spring MVC 习笔记1、Spring MVC demo2、Spring MVC 中常见注解3、数据处理3.1、请求参数处理3.2、响应数据处理 4、RESTFul 风格5、静态资源处理6、HttpMessageConverter 转换器7、过… 创作不易各位看官点赞收藏. 文章目录 Spring MVC 习笔记1、Spring MVC demo2、Spring MVC 中常见注解3、数据处理3.1、请求参数处理3.2、响应数据处理 4、RESTFul 风格5、静态资源处理6、HttpMessageConverter 转换器7、过滤器与拦截器8、 异常处理9、理解SpringMVC的执行原理10、文件上传和下载 Spring MVC 习笔记 Spring MVCSpring MVC是Spring Framework的一部分是基于java实现的MVC的轻量级Web框架。 官网文档地址:https://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/spring-framework-reference/html/mvc.html
轻量级简单易学。高效基于请求和响应的MVC框架。与Spring兼容性较好无缝结合。约定优于配置。功能强大简洁灵活。 MVC是一种软件架构思想按照软件的模型、试图、控制器进行划分。 Mmodel模型层工程中的 javaBean 用于处理数据。
Vview视图层工程中显示数据的页面用于与用户交互使用。
Ccontroller控制器层用于接收前端请求和响应浏览器。
1、Spring MVC demo 导入依赖 dependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion5.3.8/version/dependencydependencygroupIdjavax.servlet/groupIdartifactIdservlet-api/artifactIdversion2.5/version/dependencydependencygroupIdjavax.servlet.jsp/groupIdartifactIdjsp-api/artifactIdversion2.2/version/dependencydependencygroupIdjavax.servlet.jsp.jstl/groupIdartifactIdjstl/artifactIdversion1.2/version/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.21/version/dependency
/dependencies创建 web.xml 配置文件 ?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0!-- 注册DispatcherServlet--servletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!-- 关联一个spring 容器的配置文件springmvc-servlet.xml--!-- 如果它不绑定一个 spring 容器配置文件它会有一个在WEB-INF下默认名称为 springmvc-servlet.xml的配置文件--init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-servlet.xml/param-value/init-param!-- 设置该servlet在项目启动的时候就加载--load-on-startup1/load-on-startup/servlet!-- 设置请求的访问路径--servlet-mappingservlet-namespringmvc/servlet-nameurl-pattern//url-pattern/servlet-mapping
/web-app创建 spring 容器配置文件springmvc-servlet.xml ?xml version1.0 encodingUTF8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 注入映射器--bean classorg.springframework.web.servlet.handler.BeanNameUrlHandlerMapping/!-- 注入适配器--bean classorg.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter/!-- 注入视图解析器在控制器返回到视图层会根据返回路劲进行拼接--bean classorg.springframework.web.servlet.view.InternalResourceViewResolver idInternalResourceViewResolver !--前缀-- property nameprefix value/WEB-INF/jsp// !--后缀-- property namesuffix value.jsp//bean
/beans编写controller public class HelloController implements Controller {Overridepublic ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {// 创建ModelAndView对象用于返回业务的数据ModelAndView mv new ModelAndView();// 把业务获得的数据封装到mv中mv.addObject(msg,Hello,SpringMVC!);// 把要跳转的视图封装到mv中mv.setViewName(hello); // 在springmvc-servlet.xml中拼接为 /WEB-INF/jsp/hello.jsp// 把mv返回给DispatcherServletreturn mv;}
}controller 注入 Spring 容器 bean id/hello classcom.xiayuan.controller.HelloController/编写测试的页面在WEB-INF文件夹下创建一个jsp文件夹在jsp文件夹下创建hello.jsp
% page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitletest/title
/head
body${msg}
/body
/html配置 Tomcat并测试 注意在配置DisapatcherServlet时拦截的请求是 / 表示拦截所有的请求 /* 也是拦截所有的请求但是 / 不包括jsp文件而 /* 会包括jsp文件所以只能写 / 来拦截所有的请求。
2、Spring MVC 中常见注解 RequestMapping注解用于映射 url 到控制器类或一个特定的处理程序方法。用于类上表示类中的所有响应请求的方法都是以该地址作为父路径。 Controller
RequestMapping(/test)
public class HelloController {// 映射的 url 地址就是 /test/hellloRequestMapping(/hello)public String sayHello(Model model){model.addAttribute(msg,Hello,SpringMVCAnnotation!);return hello;}
}RequestMapping 注解属性
value指定 url 地址映射的值可以是一个数组映射多个请求是个必填属性支持模糊匹配。 ?单个字符。*表示任意一个或多个字符。**表示任意一层或多层目录。 method是一个枚举值可以指定请求方式来映射请求通常有POST、GET、DELETED、PUT等也是一个数组可以映射多个请求方法。params根据请求参数去匹配请求 url 地址是一个字符串数组可以指定多个指定多个时必须同时满足多个条件才会映射。 params{test,admin}请求中必须同时包含test、admin两个参数。params{“!test”}请求中必须不包含 test 参数。params{“test1”}请求中必须包含 test 参数并且参数值必须是1。params{“test!1”}请求中必须包含 test 参数并且参数值必须不等于1。 headers根据 http 请求中的请求头来映射 url 地址用法和 params 类似。consumes指定处理请求的提交内容类型Content-Type例如application/json, text/html是一个数组可以指定多个。produces 指定返回的内容类型仅当 request 请求头中的 (Accept) 类型中包含该指定类型才返回是一个数组可以指定多个。
RequestMapping 派生注解
GetMapping请求映射 GET 方式请求到方法上相当于在 RequestMapping 上添加了 method 属性为 GET 方式。PostMapping…DeleteMapping…PutMapping… RequestParam 注解用于控制器的请求方法的参数上将请求参数与方法参数两个相互映射。 GetMapping(/test1)
// 将前端的user参数与name参数映射
public String test(RequestParam(user) String name){return name;
}RequestHeader 注解用于控制器方法上的参数请求头信息与参数之间的关系映射。 PostMapping(/test1)
// 将请求头中的Accept的值赋值给header
public String test(RequestHeader(Accept) String header){return header;
}CookieValue 注解用于控制器方法上的参数将请求中的 cookie 与参数之间的关系映射起来。 PostMapping(/test1)
public String test(CookieValue String cookie){return cookie;
}Controller用于类上标识这个类是一个处理前端请求的类会根据 url 地址映射到处理请求的方法上。 Controller
public class ControllerTest {
}RestController作用与 Controller 相同但是这个类处理请求返回的结果是 json 格式。 3、数据处理
3.1、请求参数处理 请求参数每一次请求都会携带一些参数数据后端可以获取这些参数数据进行一系列操作获取请求参数的方式很多。 通过 url 中的参数来获得前端参数。
RequestMapping(/t1)
public String test1(RequestParam(name) String name, RequestParam(password) String password, Model model){// RequestParam注解中的name和password就是从前端传过来的参数名称// 必须和前端参数名称一样后面的string的名称可以和前端参数名称不一样System.out.println(name name);System.out.println(password password);return test;
}通过封装一个实体类来接受数据。
Data
AllArgsConstructor
NoArgsConstructor
public class User {private String name;private String password;
}RequestMapping(/t2)
public String test2(User user,Model model){System.out.println(user);return test;
}注意把user作为参数来接受前端数据而且前端的参数名称必须要和接受对象的字段名称保持一致不能不一样。如果字段不一样的字段就会自动为默认值。
通过 Map 集合获取数据这种方式只能从请求体中获取对象数据或则是 json 数据。
PostMapping(/test2)
public String test(RequestBody MapString,String params){System.out.println(params.get(name));return ok;
}请求参数乱码问题在前端传入的参数中有中文字符在后端就会存在乱码问题我们通常使用过滤器去解决乱码问题。 !-- 向 web.xml 文件中注册一个 filer 过滤器就可以解决乱码问题--filterfilter-nameencoding/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueutf-8/param-value/init-param!-- 设置响应编码--init-paramparam-nameforceResponseEncoding/param-nameparam-valuetrue/param-value/init-param
/filter
filter-mappingfilter-nameencoding/filter-nameurl-pattern/*/url-pattern
/filter-mapping3.2、响应数据处理 request 域数据设置 ModelAndView这是之前的数据封装方式使用的就是ModelAndView来给前端显示数据的。
Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {ModelAndView mv new ModelAndView();// 数据mv.addObject(msg,封装的数据!); // 视图的名称mv.setViewName(hello);return mv;
}ModelMap:
RequestMapping(/t3)
public String test3(ModelMap modelMap){modelMap.addAttribute(msg,封装的数据);return test;
}Model:
RequestMapping(/t4)
public String test4(Model model){model.addAttribute(msg,封装的数据);return test;
}注意ModelMap 它继承了 LinkedHashMap所有他有该类的所有操作而 Model 是 ModelMap 的简洁版本没有继承 LinkedHashMap。
Model 只有寥寥几个方法只适合用于储存数据简化了新手对于Model对象的操作和理解 ModelMap 继承了 LinkedMap 除了实现了自身的一些方法同样的继承 LinkedMap 的方法和特性 ModelAndView 可以在储存数据的同时可以进行设置返回的逻辑视图进行控制展示层的跳转它们都是把数据封装到在 request 域中的实际上在底层返回中请求都是返回的一个 ModelAndView 对象。 session 域数据这个数据是当前会话共享的数据。 GetMapping(/test)
public String test(HttpServletSession session){
session.setAttribute(data,这是一个数据);
return ok;
}application 域数据这个数据是应用程序共享的数据。 GetMapping(/test)
public String test(HttpSession session){// 应用全局上下文ServletContext context session.getServletContext();context.setAttribute(data,这是一个数据);return ok;
}请求转发 RequestMapping(/t2)
public String test2(HttpServletRequest request, HttpServletResponse response,Model model){// 请求转发可以转发到页面也可以转发到一个请求return forward:/test return forward:/login.jsp;
}重定向 RequestMapping(/t2)
public String test2(HttpServletRequest request, HttpServletResponse response,Model model){// 相当于重新发出一个请求return redirect:/login.jsp
}注意重定向不能重定向到WEB-INF下的资源。
4、RESTFul 风格 Restful是一个资源定位及资源操作的风格是标准也不是协议只是一种风格。基于这个风格设计的软件可以更简洁更有层次更易于实现缓存等机制。 操作传统方式RESTFul风格查询getById?id1getById/1 get方式新增insertinsert post方式删除deletedByid?id1deletedByid/1 delete方式更新updateByid?id1updateByid/1 put方式 url 地址参数绑定 Controller
public class RestFulController {RequestMapping(/hello/{a}/{b})public String test(PathVariable String a, PathVariable String b, Model model){// 需要使用PathVariable注解来注解参数上面a和b就是参数的名称。model.addAttribute(msg,Hello,RestFul!);return hello;}
}5、静态资源处理 注意在 Spring MVC 中所有的请求都会先呗被 DispatcherServlte 拦截并且映射到对应的控制器上但是对于静态资源就会出现找不到的问题。 !-- 解决需要在 Spring MVC 配置文件中指定处理静态资源的 Sevlet --
?xml version1.0 encodingUTF8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 加入处理静态资源的 servlet--mvc:default-servlet-handler/!-- 开启注解驱动不开启静态资源 servlet 无效--mvc:annotation-driven/
/beans处理流程 6、HttpMessageConverter 转换器 消息转换器将请求信息转换成 Java 对象或者将 Java 对象装换成响应报文给前端。HttpMessageConverter 提供了两个注解和两个实体类RequestBody、ResponseBody、RequestEntity、ResponseEntity。 RequestBody获取请求体中的参数与方法参数绑定在一起一般请求方式是 POST 方法也可以是 GET 方法但是必须有请求体。
PostMapping(/)
public String fun1(RequestBody User user){ // 将请求体的参数与user对象进行映射参数名需要对应return ok;
}RequestEntity封装请求报文的一种类型其中包含请求头、请求体等信息在控制器方法上指定这个采参数就可以直接获取请求信息。
PostMapping(/entity)
public String fun2(RequestEntityString entity){System.out.println(entity.getHeaders());System.out.println(entity.getBody());return ok;
}ResponseBody标识在控制器方法上如果项目引入了 Json 解析包对于返回的对象会解析成 Json 字符串。
GetMapping(/)
// 将方法返回值作为响应体不再是视图名臣
ResponseBody
public User fun3(){User user new User();user.setUsername(张三);user.setPassword(123456);return user;
}ResponseEntity用于控制器方法的返回值该方法的返回值就是响应到浏览器的响应报文。
GetMapping(/entity)
public ResponseEntityUser fun4(){User user new User();user.setUsername(张三);user.setPassword(123456);// 构建响应报文return new ResponseEntity(user, HttpStatus.OK);
}7、过滤器与拦截器 过滤器是基于函数回调的过滤器中都会实现一个 doFilter()方法这个方法有一个FilterChain 参数而实际上它是一个回调接口。ApplicationFilterChain是它的实现类 这个实现类内部也有一个 doFilter() 方法就是回调方法。 // 自定义过滤器
Component
public class MyFilter implements Filter {// 初始化方法这个方法必须执行成功否则过滤器不生效Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 进行业务处理如果不放行就通过request重定向或转发到对应页面// 放行请求filterChain.doFilter(servletRequest,servletResponse);}// 拦截器销毁方法Overridepublic void destroy() {Filter.super.destroy();}
}拦截器应用中可以同时存在多个拦截器Interceptor 一个请求也可以触发多个拦截器 而每个拦截器的调用会依据它的声明顺序依次执行拦截器 则是基于 Java 的反射机制动态代理实现的只有 Spring MVC 框架才能使用该拦截器。 // 自定义拦截器
Component
public class MyInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return false;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}preHandle方法是过滤请求相当于 servlet 中的 doFilter如果返回 true 就放行该请求返回 false 就不会放行请求。postHandle方法在控制器方法执行完成之后执行。afterCompletion方法在视图解析器解析之后执行。 过滤器的使用编写配置类将过滤器注册到 Spring 容器中并设置对应的拦截路径。 Configuration
public class WebMvcConfig {Bean(myFilterRegister)public FilterRegistrationBeanMyFilter myFilter(MyFilter myFilter) {FilterRegistrationBeanMyFilter registrationBean new FilterRegistrationBean();registrationBean.setFilter(myFilter);registrationBean.addUrlPatterns(/*); //url拦截不配置拦截所有请求registrationBean.setOrder(1); // 过滤顺序越小越先过滤return registrationBean;}
}拦截器的使用(方式一)将拦截器通过 XML 方式注入到 Spring 容器中。 mvc:interceptorsmvc:interceptor!-- 设置拦截的路径--!-- /** 表示该文件夹下的所有请求--!-- /* 表示所有的请求--mvc:mapping path/admin/**/ !-- 表示拦截admin下面的所有文件夹进行拦截--!-- 使用哪个拦截器来拦截--bean classcom.xiayuan.interceptor.MyInterceptor//mvc:interceptor
/mvc:interceptors拦截器的使用(方式二)通过配置类的方式注入到 Spring 容器中。 Configuration
public class WebMvcConfig implements WebMvcConfigurer {// 注册拦截器Overridepublic void addInterceptors(InterceptorRegistry registry) {// order越小越先拦截registry.addInterceptor(new MyInterceptor()).addPathPatterns(/**).order(1);}
}执行流程 多个拦截器执行顺序多个拦截器主要是通过配置顺序进行执行也可以通过配置 order 设置执行顺序。 拦截器都放行preHandle 方法按照拦截器依次执行postHandle、afterCompletion会按照拦截器顺序倒序执行。
存在拦截器拦截preHandle 方法按照拦截循序执行被拦截以及后面的拦截器对应的 preHandle 都不执行。postHandle 所有拦截器都不会执行afterCompletion 只会执行未被拦截的拦截器并且倒序执行(有一个拦截器执行的 index 记录执行拦截器的下标)。
8、 异常处理 针对异常不想显示为 Spring Mvc 默认的异常处理可以之定义异常控制器来处理指定的异常。 // 实质就是一个 Controller 控制器
// ControllerAdvice 方法返回结果是视图名称
RestControllerAdvice // 方法返回结果是 json 字符串
public class GlobalExceptionHandler {private static final Logger log LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 拦截未知的运行时异常参数是一个指定处理异常的 Class 对象*/ExceptionHandler(value {RuntimeException.class,NullPointerException.class})public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {String requestURI request.getRequestURI();log.error(请求地址{},发生未知异常., requestURI, e);return AjaxResult.error(e.getMessage());}
}9、理解SpringMVC的执行原理 Spring MVC 的原理图 深入理解 Spring MVC 原理 中心控制器DispatcherServlet
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。
Spring MVC框架像其他其它MVC框架一样以请求为驱动围绕一个中心控制器的servlet派送请求和提供功能中心控制器实际上就是一个servlet它是继承至HttpServlet基类。所有的请求给中心控制器来拦截然后在派送请求。
分析执行流程
DispatcherServlet表示前置控制器是整个SpringMVC的控制中心。用户发出请求DispatcherServlet接收请求并拦截请求。HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器。HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。HandlerAdapter表示处理器适配器其按照特定的规则去执行Handler。Handler让具体的Controller执行。Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。视图解析器将解析的逻辑视图名传给DispatcherServlet。DispatcherServlet根据视图解析器解析的视图结果调用具体的视图。最终视图响应给用户。
10、文件上传和下载 导入相应的依赖 dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.3/version
/dependency
dependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion4.0.1/version
/dependency配置文件解析器 !--文件上传配置--
bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver !-- 请求的编码格式必须和jSP的pageEncoding属性一致以便正确读取表单的内容默认为ISO-8859-1 --property namedefaultEncoding valueutf-8/ !-- 上传文件大小上限单位为字节1048576010M --property namemaxUploadSize value10485760/property namemaxInMemorySize value40960/
/bean注意必须配置id属性因为这个是根据id获取的bean的id属性的名称必须是multipartResolver。 文件上传控制器(方式一) public String upload(RequestParam(my_file) CommonsMultipartFile file , HttpServletRequest request) throws IOException{//获取文件名 : file.getOriginalFilename();String uploadFileName file.getOriginalFilename();// 如果文件名为空直接回到首页if (.equals(uploadFileName)){return redirect:/index.jsp;}System.out.println(上传文件名 : uploadFileName);// 上传路径保存设置String path request.getServletContext().getRealPath(/upload);// 如果路径不存在创建一个 File realPath new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println(上传文件保存地址realPath);InputStream is file.getInputStream(); //文件输入流OutputStream os new FileOutputStream(new File(realPath,uploadFileName));// 文件输出流// 读取写出int len0;byte[] buffer new byte[1024];while ((lenis.read(buffer))!-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return redirect:/index.jsp;
}文件上传控制器(方式二) /* * 采用file.Transto 来保存上传的文件 */
RequestMapping(/upload2)
public String fileUpload2(RequestParam(my_file) CommonsMultipartFile file, HttpServletRequest request) throws IOException {//上传路径保存设置String path request.getServletContext().getRealPath(/upload);File realPath new File(path);if (!realPath.exists()){realPath.mkdir();}// 上传文件地址System.out.println(上传文件保存地址realPath);// 通过CommonsMultipartFile的方法直接写文件注意这个时候file.transferTo(new File(realPath / file.getOriginalFilename()));return redirect:/index.jsp;}
}文件下载(方式一)通过超链接来下载文件但是存在一个弊端超链接下载文件对于浏览器能够解析的资源就直接在页面给你展示浏览器不能够解析的资源会让你下载。 a href${pageContext.request.contextPath}/upload/lab.png通过超链接下载/a文件下载(方式二) RequestMapping(value/download)
public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception {//要下载的图片地址String path request.getServletContext().getRealPath(/upload);String fileName lab.png;// 1、设置response 响应头response.reset();// 设置页面不缓存,清空bufferresponse.setCharacterEncoding(UTF-8);// 字符编码response.setContentType(multipart/form-data);// 二进制传输数据// 设置响应头response.setHeader(Content-Disposition,attachment;fileName URLEncoder.encode(fileName, UTF-8));File file new File(path,fileName);// 2、 读取文件--输入流InputStream inputnew FileInputStream(file);// 3、 写出文件--输出流OutputStream out response.getOutputStream();byte[] buff new byte[1024];int index0;// 4、执行 写出操作while((index input.read(buff))! -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;
}