SpringMVC

视图解析

  请求处理方法(controller方法)执行完成后,最终返回一个 ModelAndView 对象,即使出现异常也会返回一个 ModelAndView 对象。对于那些返回 String,View 或 ModeMap 等类型的处理方法,Spring MVC 也会在内部将它们装配成一个 ModelAndView 对象,它包含了逻辑名和模型对象的视图,由视图解析器解析视图,然后,进行页面的跳转。

  Spring MVC 借助视图解析器ViewResolver)得到最终的视图对象(View),最终的视图可以是 JSP ,也可能是 Excel、JFreeChart等各种表现形式的视图

视图View

  视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户

    1. 将数据存放到域中   request.setAttribute(name,value)

    2. 转发|重定向       rd.forward(request,response);

  为了实现视图模型和具体实现技术的解耦,Spring 在 org.springframework.web.servlet 包中定义了一个高度抽象的 View 接口

  视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全的问题

常用的视图实现类

  转发视图:InternalResourceView

  转发视图:JstlView 需导入Jstl的jar包,适配器会自动调用此解析器,此解析器继承了InternalResourceView

    若使用 JSTL 的 fmt 标签则需要在 SpringMVC 的配置文件中装配标准资源文件bean

  重定向视图:RedirectView

    一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理

    如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和 redirect: 当成指示符,其后的字符串作为 URL 来处理

    在返回值中 return "redirect:/success_redirect.jsp";解析器会自动重定向到此页面,不需在前面加工程路径名RedirectView会自动帮我们追加上

注意

转发:访问 WEB-INF 下路径时只允许当前请求为GET或POST请求模式的才能转发成功,(也就是浏览器只支持GET、POST请求的转发)默认携带当前的请求方式发起转发请求。

   访问 Controller 内部路径时必须加上前缀 forward: 同样携带当前的请求方式发起请求,必须有对应的请求方式的路径

重定向:必须先加上前缀 redirect: 访问 WEB-INF 下的路径不被允许,默认用 GET 方法发起新的请求。

    访问 Controller 内部路径时同样只能重定向到GET请求方式的路径

视图解析器ViewResolver

  SpringMVC 为逻辑视图名的解析提供了不同的策略,可以在 SpringMVC 上下文中配置一种或多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。通过反射原理

  视图解析器的作用比较单一:将逻辑视图解析为一个具体的视图对象

    url= getPrefix() + viewName + getSuffix()

  每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性,可以通过 order 属性指定解析器的优先顺序,order  越小优先级越高。

  JSP 是最常见的视图技术,可以使用默认的 InternalResourceViewResolve 作为视图解析器

  BeanNameViewResolver:将逻辑视图名解析为一个 Bean , Bean 的 id 等于逻辑视图名

Spring表单标签

  SpringMVC 的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显

  引入标签库

  1. <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

form 标签

  <form:form> 标签  可以通过 modelAttribute 属性指定绑定的模型属性,若没有指定该属性,则默认从 request 域对象中读取 command 属性的表单 bean,如果该属性值也不存在,则会发生错误。

  SpringMVC 提供了多个表单组件标签用以绑定表单字段的属性值,如 <form:input/>(同html标签中 input type="text"),它们的共有属性:

    • path表单字段,对应 html 元素的 name 属性,支持级联属性
    • htmlEscape:是否对表单值的 HTML 特殊字符进行转换,默认值为 true
    • cssClass:表单组件对应的 CSS 样式类名
    • cssErrorClass:表单组件的数据存在错误时,采取的 CSS 样式

  form:input、form:password、form:hidden、form:textarea:对应 HTML 表单的 text、password、hidden、textarea 标签

  form:radiobutton:单选框组件标签,当表单 bean 对应的属性值和 value 值相等时,单选框被选中

  form:radiobuttons:单选框组标签,用于构造多个单选框

    • items:可以是一个 List、String[] 或 Map
    • itemValue:指定 radio 的 value 值。可以是集合中 bean 的一个属性值
    • itemLabel:指定 radio 的 label 值
    • delimiter:多个单选框可以通过 delimiter 指定分隔符

  form:checkbox:复选框组件。用于构造单个复选框

  form:checkboxs:用于构造多个复选框。使用方式同 form:radiobuttons 标签

  form:select:用于构造下拉框组件。使用方式同 form:radiobuttons 标签

  form:option:下拉框选项组件标签。使用方式同 form:radiobuttons 标签

  form:errors:显示表单组件或数据校验所对应的错误

    • <form:errors path= “*” /> :显示表单所有的错误
    • <form:errors path= “user*” /> :显示所有以 user 为前缀的属性对应的错误
    • <form:errors path= username /> :显示特定表单对象属性的错误
  1. //修改功能需要增加绝对路径,相对路径会报错,路径不对
  2. <form:form action="${pageContext.request.contextPath }/emp" method="POST" modelAttribute="employee(command)">
  3. LastName:<form:input path="lastName"/><br><br>
  4. Email:<form:input path="email"/><br><br>
  5. Gender:<form:radiobuttons path="gender" items="${genders }"/><br><br>
  6. Dept:
  7. <form:select path="department.id" items="${depts }"
  8.      itemLabel="departmentName" itemValue="id">
  9. </form:select>
  10. <br><br>
  11. <input type="submit" value="添加员工信息">
  12. </form:form>

通过jQuery转换为DELETE请求

  REST风格代码,要求删除功能,必须以DELETE方式提交。解决方案

    1. 准备一个以DELETE方式提交的form表单

    2. 通过单击事件为准备好的form表单action属性赋值。

    3. 触发表单的submit事件

  1. $(function(){
  2.   $(".delete").click(function(){
  3.     var href = $(this).attr("href");
  4.     $("form").attr("action",href).submit();
  5.     return false ;
  6.   });
  7. });

SpringMVC 处理静态资源

  若将 DispatcherServlet 请求映射配置为 /, 则 Spring MVC 将捕获 WEB 容器的所有请求, 包括静态资源的请求, SpringMVC 会将他们当成一个普通请求处理, 因找不到对应处理器将导致错误。从而无法加载静态资源

  解决: 需要在 SpringMVC 的配置文件中配置 <mvc:default-servlet-handler/> 它将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是静态资源的请求,就会由此处理器处理

    并且还需要配置<mvc:annotation-driven />,因为只配置上面一个所有请求又全部只由默认处理器来处理请求了

底层原理:Tomcat解析Servlet优先级问题

  程序员定义的 Servlet优先级大于Tomcat自己的Servlet

  URL中default-servlet配置 "*.jsp" 大于 "/" 的配置。

处理JSON和下载

HttpMessageConverter<T>

  HttpMessageConverter<T> 是 Spring3.0 新添加的一个接口,负责将请求信息转换为一个对象(类型为 T),将对象(类型为 T)输出为响应信息

  当控制器处理方法使用到 @RequestBody/@ResponseBody 或 HttpEntity<T>/ResponseEntity<T> 时, Spring 首先根据请求头或响应头的 Accept 属性选择匹配的 HttpMessageConverter,  进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错 406

  HttpMessageConverter<T> 可将请求信息转化并绑定到(controller)处理方法的入参中或将响应结果转为对应类型的响应信息

SpringMVC处理 json

  1) jackson-annotations-2.1.5.jar

    jackson-core-2.1.5.jar

    jackson-databind-2.1.5.jar

  2)需要在配置文件设置 <mvc:annotation-driven />

    如此可将适配器AnnotationMethodHandlerAdapter升级为:RequestMappingHandlerAdapter 而 RequestMappingHandlerAdapter 适配器中存在MappingJackson2HttpMessageConverter

  3)@RequestBody / @ResponseBody 在处理方法上进行标注

      @RequestBody:是将Http请求正文插入到处理方法中,修饰目标方法的入参

      @ResponseBody:是将内容或对象作为Http响应正文返回去

将user对象转为json对象返回,注意ajax设置dataType:"json"类型

  1. @ResponseBody
  2. @RequestMapping(value = "/json",method = RequestMethod.GET)
  3. public User json(String string){
  4. return user;
  5. }

异步请求

  1. $("#username1").change(function () {
  2. var username = $("#username1").val();
  3. var dat = {
  4. "username":username,
  5. "_method":"PUT",
  6. };
  7. $.ajax({
  8. url:"${pageContext.request.contextPath}/login",
  9. type:"POST",
  10. data:dat,
  11. dataType:"json",
  12. success:function (data) {
  13. alert(data.name);
  14. },
  15. error:function () {
  16. alert("请求失败");
  17. }
  18. });
  19. });

  HttpEntity<T>        作为处理方法的入参获取文件大小请求头等

  ResponseEntity<T>   作为处理方法的返回值,返回客户端要下载的文件资源,实现文件下载功能

 下载

  1. @RequestMapping(value = "/downLoad",method = RequestMethod.GET)
  2. public ResponseEntity<byte[]> testDownLoad(HttpServletRequest request,HttpServletResponse response) throws IOException {
  3. ResponseEntity<byte[]> responseEntity = null;
  4. //1.获取到download文件的真实路径(推荐先放在项目根目录下测试_downLoad为文件名)
  5. String path = request.getServletContext().getRealPath("/downLoad");
  6. //在请求体中获取文件名
  7. String fileName = request.getParameter("fileName");
  8. //2.通过真实文件路径创建File对象(File.separator为当前系统文件分隔符)
  9. File file = new File(path + File.separator + fileName);
  10. //3.创建文件输入流,将要下载的文件读取到程序中
  11. FileInputStream fileInputStream = new FileInputStream(file);
  12. byte[] bytes = new byte[fileInputStream.available()];
  13. //将文件一次性全部读取到bytes中
  14. fileInputStream.read(bytes);
  15. //解决 文件名 中文乱码问题
  16. String header = request.getHeader("User-Agent");
  17. if(header != null && header.contains("Firefox")) {
  18. fileName = "=?utf-8?B?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?=";
  19. }else {
  20. fileName = URLEncoder.encode(fileName, "UTF-8");
  21. }
  22. //创建响应头
  23. HttpHeaders httpHeaders = new HttpHeaders();
  24. httpHeaders.add("Content-Disposition", "attachment; filename="+fileName);
  25. //返回资源(HttpStatus.OK=200)
  26. responseEntity = new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
  27. fileInputStream.close();
  28. return responseEntity;
  29. }

文件上传

  Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的 MultipartResolver 实现的。实现类:CommonsMultipartResolver 

  Spring MVC 上下文中默认没有装配 MultipartResovler,因此默认情况下不能处理文件的上传工作,需在上下文中配置 MultipartResolver

配置 MultipartResolver

  defaultEncoding: 必须和用户 JSP 的 pageEncoding 属性一致,以便正确解析表单的内容,为了让 CommonsMultipartResolver 正确工作,必须先将 Commons-fileupload 及 Commons-io 的 jar 包添加到类路径下。

  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  2. <property name="defaultEncoding" value="UTF-8"></property>
  3. <property name="maxUploadSize" value="10240000"></property>
  4. </bean>

  MultipartResolver 用于处理文件上传,当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller

上传文件

  1. <form action="${pageContext.request.contextPath}/upLoad" method="post" enctype="multipart/form-data">
  2. 需上传文件:<input type="file" name="file">
  3. <input type="submit">
  4. </form>
  1. @RequestMapping(value = "/upLoad",method = RequestMethod.POST)
  2. public String upLoad(@RequestParam("file")MultipartFile multipartFile,HttpServletRequest request) throws IOException {
  3. //1.获取upload的真实路径
  4. String path = request.getServletContext().getRealPath("/upLoad");
  5. //如果此路径不存在则创建此目录
  6. File file1 = new File(path);
  7. if(!file1.exists()){
  8. file1.mkdir();
  9. }
  10. //2.获取要上传的文件名
  11. String filename = multipartFile.getOriginalFilename();
  12. //3.创建上传file
  13. File file = new File(path + File.separator + filename);
  14. //4.实现文件上传
  15. multipartFile.transferTo(file);
  16. return "home";
  17. }

多文件上传

Java框架之SpringMVC 04-视图解析-Spring表单-JSON-上传下载的更多相关文章

  1. 【温故知新】Java web 开发(三)Form表单与上传下载文件

    简介:在一和二的基础之上,这次来记录下如何在页面提交表单数据,以及文件的上传和下载整个流程,请求也不仅限于GET了,也有POST了. 1. 为了方便,在 webapp 下直接新建一个 index.ht ...

  2. Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request对象方法,属性和Response对象,form表单的上传

    Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request请求对象方法,属性和Response响应对象,form表单的上传 一丶CBV和FBV       在Django中存 ...

  3. Java模拟表单POST上传文件

    JAVA模拟表单POST上传文件 import java.awt.image.BufferedImage;import java.awt.image.ColorModel;import java.io ...

  4. Spring实现文件的上传下载

    背景:之前一直做的是数据库的增删改查工作,对于文件的上传下载比较排斥,今天研究了下具体的实现,发现其实是很简单.此处不仅要实现单文件的上传,还要实现多文件的上传. 单文件的下载知道了,多文件的下载呢? ...

  5. spring boot:单文件上传/多文件上传/表单中多个文件域上传(spring boot 2.3.2)

    一,表单中有多个文件域时如何实现说明和文件的对应? 1,说明和文件对应 文件上传页面中,如果有多个文件域又有多个相对应的文件说明时, 文件和说明如何对应? 我们在表单中给对应的file变量和text变 ...

  6. Spring Boot2(十四):单文件上传/下载,文件批量上传

    文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...

  7. SpringMVC 视图和视图解析器&表单标签

    视图和视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView 对象.对于那些返回 String,View 或 ModeMap 等类型的处理方法,Spring MVC 也会在内部将它 ...

  8. Yii框架2.0的视图和widgets表单的使用

    2.0的控制器的创建和action方法的添加和1.0的基本是一样的.但我发现他的widgets 的ActiveForm和1.1版本有些不一样的地方. 对于视图基本也是一样的,有render 和 ren ...

  9. Spring Boot 教程 - 文件上传下载

    在日常的开发工作中,基本上每个项目都会有各种文件的上传和下载,大多数文件都是excel文件,操作excel的JavaAPI我用的是apache的POI进行操作的,POI我之后会专门讲到.此次我们不讲如 ...

随机推荐

  1. .map() .filter() .reduce() .includes() .some() .every()的用法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 28款GitHub最流行的开源机器学习项目,推荐GitHub上10 个开源深度学习框架

    20 个顶尖的 Python 机器学习开源项目 机器学习 2015-06-08 22:44:30 发布 您的评价: 0.0 收藏 1收藏 我们在Github上的贡献者和提交者之中检查了用Python语 ...

  3. Java 注解与单元测试

    注解 Java注解是在JDK1.5 之后出现的新特性,用来说明程序的,注解的主要作用体现在以下几个方面: 编译检查,例如 @Override 编写文档,java doc 会根据注解生成对应的文档 代码 ...

  4. Find工具

    Find工具主要用于操作系统文件.目录的查找, 1.语法参数格式为: Find工具的语法格式:find path(路径) -option(参数) action(动作): PATH路径:可以任意路径.绝 ...

  5. 【Docker】安装MySQL彻底解决3306端口占用问题

    1.问题闪现: 初次up mysql报3306端口被占用 yunduo@YunDuo:~/Work/Learning/Docker/docker_compose$ docker-compose up ...

  6. mapper的配置文件

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-// ...

  7. Python3 安装pylint 及与PyCharm关联

    使用如下命令: pip3 install pylint 安装完后可以看到在你的python3的目录底下的Scripts目录下有pylint.exe了 然后就可以使用pylint 评估你的代码了,如: ...

  8. Linux基础:Linux下常用命令

    常用命令 shutdown ​ 用来系统关机命令.shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作. ​ shutdown (选项)(参数) -c: 当执行"s ...

  9. 为什么IIS应用程序池回收时间默认被设置为1740分钟?

    作者:斯科特 福赛斯/Scott Forsyth日期:2013/04/06地址:http://weblogs.asp.net/owscott/why-is-the-iis-default-app-po ...

  10. 【转载】JavaScript术语:shim 和 polyfill

    在学习和使用 JavaScript 的时候,我们会经常碰到两个术语:shim 和 polyfill.它们有许多定义和解释,意思相近又有差异. Shim Shim 指的是在一个旧的环境中模拟出一个新 A ...