SpringMVC框架

知识点回顾:

  1. SpringMVC基于maven的项目构建
  2. 配置 web.xml 文件【配置大C, 以及配置编码过滤器】, 建议CV大法
  3. 编写WebMvcConfig 配置类,建议 CV 大法
  4. 开发 控制器类,这个完全由需求决定
  5. 开发 jsp
  6. 如有需要,添加 业务层 和 持久层
    1. 导入配置了 业务层和持久层 的配置类 AppConfig
    2. 在控制层中自动注入 业务层

有关请求参数的获取

有关编码的问题

有关静态资源的问题

有关视图解析器的问题

文件上传和下载

普通的请求数据都是以字符串的形式传递的,

而文件类型的数据是以二进制流的形式传递的

回忆一下表单中的属性:

> ...
> <form name="表单名" action="服务端资源名" method="get|post" 
>       enctype="application/x-www-form-urlencoded">
>     <input type="xxxx" />
>     ...
> </form>
> ```
>
> 注:
>
> enctype属性指定表单数据编码格式,默认是 application/x-www-form-urlencoded
>
> 如果你要做文件的上传,则这个表单要满足两个条件
>
> 1. method属性值必需是 post
> 2. enctype属性值必需是 multipart/formdata

上面是针对前端页面中的form表单所做的要求,下面,我们再来看一下服务端[后台]的代码要求:

在SpringMVC中,它是基于一个叫 MultipartResolver 的接口来处理Multipart数据,它有两个实现类:

* [CommonsMultipartResolver](https://docs.spring.io/spring/docs/4.3.24.RELEASE/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartResolver.html),  基于第三方的组件[apache commons fileupload组件 ]
* StandardServletMultipartResolver 基于Servlet3.0规范中提供的 Part API

如何配置和使用

1. 在pom.xml中,引入 fileupload依赖
2. 编写 jsp 页面
3. 开发 控制器类
4. 在配置类中,添加 MultipartResolver 的Bean

## 前置控制器【大C】的执行流程 

> DispatcherServlet是SpringMVC框架提供的一个核心处理类,它负责拦截"所有请求",然后再去“分发[dispatch]”这些请求到你自己定义的资源,这个资源可以是控制器,也可以是其它资源。
>
> 通过 @RequestMapping 来请求的URL 和 对应的 控制器的方法 “映射[mapping]"起来。



首先,大C接收到客户端的请求后,先查询在SpringMVC容器范围内去查找是否有对应的 RequestMapping, 如果有找到,则生成一个请求执行链。

其次,由这个请求执行链去执行目标的控制器的匹配方法。同时,容器会帮我们生成一个 HandlerAdapter 适配器,再由这个适配器去创建 ModelAndView

第三,ModelAndView 会传递给我们的目标方法,由我们自己去准备“数据”以及决定跳转到哪个视图。

第四,容器会判断你是否配置了视图解析器,如果配置了,则由视图解析器[XXXViewResolver]去解析我们想要得到的视图

第五,我们是否配置了拦截器[Interceptor],由根据匹配决定是否要进入拦截器

第六,我们是否配置了异常处理器[ExceptionHandler],由配置决定如何做异常处理

。。。

。。。

第七,最后执行会回到 大C, 由大C来响应客户端

## 响应[HttpServletResponse]

> SpringMVC框架默认情况下,采用JSP做为视图,当然,我们在@RequestMapping中,通过设置  produces 属性来指定响应客户端的数据格式,再通过 @ResonpseBody 告诉容器,直接以方法的返回值做为响应的内容

步骤:

1.  在pom.xml中,添加对 json 数据解析的依赖,这个依赖可以是 Spring自带的,也可以是第三方的。如下:

   ```xml
   <!-- 使用spring自带的json处理依赖包 -->
           <dependency>
               <groupId>com.fasterxml.jackson.core</groupId>
               <artifactId>jackson-core</artifactId>
               <version>2.6.0</version>
           </dependency>
           <dependency>
               <groupId>com.fasterxml.jackson.core</groupId>
               <artifactId>jackson-databind</artifactId>
               <version>2.6.0</version>
           </dependency>
           <dependency>
               <groupId>com.fasterxml.jackson.core</groupId>
               <artifactId>jackson-annotations</artifactId>
               <version>2.6.0</version>
           </dependency>
  1. 控制器中,在@RequestMapping注解中,添加 produces属性,指定响应的数据格式为 application/json,再打上@ResonpseBody 注解,如下:
   @RequestMapping(value = "/account",produces = "application/json"
                       ,method = RequestMethod.POST)
       @ResponseBody //直接把方法的返回值当做响应的数据给到客户端
       public Account getAccountForJson() {
           //模拟一个帐户
           Account a = new Account();
           a.setOwner("张三丰");
           a.setBalance(18000);
           a.setId(1);
           //再创建一个User
           User user = new User("zhangsf","张君宝","123456");
           a.setUser(user);
           //返回
           return a;
       }
  1. 打开浏览器,发送请求,查看返回的 json 数据。

注:如果你想返回 xml 格式数据,则需要在实体类中,打上JAXB的注解。有关JAXB的操作,请查看相关手册。

Restful风格的URL

它是一种把请求数据传递到服务端的方式,传统的get请求采用查询字符串的方式来传递数据,如:

传统的方式: http://host:port/appname/resource?username=jack&password=123456

RestFul方式:http://host:port/appname/resource/jack/123456

首先,SpringMVC框架是完全支持RestFul风格的,它的优点是:

  • 简洁、优美
  • 效率高

如何在SpringMVC中,开发出符合RestFul风格的控制器呢?

  1. 控制器上面使用的注解不再是 @Controller, 而是变成了 @RestController
  2. 在方法中,使用@RequestMapping填写匹配的url时,通过{占位符}来指定接收的变量
  3. 在方法中,使用 @PathVariable 注解来接收参数
  4. 注意:由于@RestController中使用了 @ResponseBody注解,所以,方法的返回值会被当做数据响应给客户端,如果你想跳转到jsp视图,则可以把方法设计成返回 ModelAndView 类型,并返回 ModelAndView

使用RestFul风格做CRUD操作,刚好可以对应请求Method中的四个类型,如下:

​ R操作,也就是获取、查询操作,匹配 GET 请求

​ C操作,也就是创建,新增, 匹配 POST 请求

​ U操作, 也就是更新、修改,匹配 PUT 请求

​ D操作, 也就是删除, 匹配 DELETE 请求

有关 HTTPSession 操作

我们有时需要在 session 范围内绑定对象,传统的做法是:

> @RequestMapping
> public String normalSession(HttpSession session) {
>     //通过业务对象来获取了用户对象
>     User user = xxxx;
>     //把它绑定Session范围
>     session.setAttribute("LOGIN_USER", user);
>     //跳 转
>     ...
>     return "....";
> }
> ```
>
> 以上的做法是完全可以的。
>
> 在SpringMVC中,我们也可以通过 `@SessionAttribute`注解来帮助我们取出存放到 session范围内的对象并自动注入到被修饰 的参数中。

如:

```java
@RequestMapping("/session/special")
public String demo2(@SessionAttribute("USER_KEY") User user, Model model) {
    //
    System.out.println(user);
    return "result";
}

它的作用就是从 session范围取出一个名为 USER_KEY 的绑定对象,如果在session范围这个KEY,则会出现400错误,如果出现,则把对象注入到 user参数中,方便我们使用。

注: