SpringMVC框架入门(上)

一、SpringMVC

1. 什么是MVC

MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分

  1. M:Model,模型层,指的是工程中的JavaBean,作用是处理数据
    JavaBean分为两类:
        一类称为实体类Bean:专门存储业务数据的,如 Student、User 等
        一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理业务逻辑和数据访问。
  2. V:View,视图层,指的是工程中的html或jsp页面,作用是与用户进行交互,展示数据
  3. C:Controller,控制层,指的是工程中的servlet,作用是接收请求和相应浏览器。
  4. MVC工作流程:用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,然后将结果返回到ControllerController再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器。

2. 什么是SpringMVC

SpringMVC是Spring的一个后续产品,是Spring的一个子项目

SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案
注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet

3. SpringMVC的作用

  1. SpringMVC负责与用户进行交互,主要处理数据的获取、返回及页面的跳转、重定向。

  2. Servlet缺点:

    1. 一个Servlet只能完成一个业务处理
    2. 每个Servlet的配置信息至少8行
    3. 利用HttpServletRequest是获取客户端参数唯一方法, 并且获取的参数类型都是String, 可能需要做转换处理
    4. Servlet处理用户的请求类型比较单一(doGet/doPost)

    url:localhost:8080/addUser?id=1&name=bingo&birthday=2020-02-02
    String id = HttpServletRequest.getParameter(“id”);

  3. SpringMVC优点:

    1. 利用一个Controller类, 完成某项业务的全部调用
    2. 简化了配置
    3. 参数获取非常灵活

二、@RequestMapping注解

1. 功能

  1. 从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。
  2. SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

2. 位置

  1. @RequestMapping标识一个类:设置映射请求的请求路径的初始信息

  2. @RequestMapping标识一个方法:设置映射请求请求路径的具体信息

@Controller
@RequestMapping("/test")
public class RequestMappingController {

	//此时请求映射所映射的请求的请求路径为:/test/testRequestMapping
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        return "testReqMapping";
    }
}

3. value属性

  1. @RequestMapping注解的value属性通过请求的请求地址匹配请求映射

  2. @RequestMapping注解的value属性是一个字符串类型的数组,表示该请求映射能够匹配多个请求地址所对应的请求

  3. @RequestMapping注解的value属性必须设置,至少通过请求地址匹配请求映射

<a th:href="@{/testRequestMapping}">测试@RequestMapping的value属性-->/testRequestMapping</a><br>
<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
@RequestMapping(
        value = {"/testRequestMapping", "/test"}
)
public String testRequestMapping(){
    return "testReqMapping";
}

注:value属性的值可以有多个,如上,有"/testRequestMapping"和"/test",浏览器发送请求时,只要满足这里面的任一个,即可跳转到success.html,也就是说value属性值之间的关系是 “或”

4. method属性

  1. @RequestMapping注解的method属性通过请求的请求方式(get或post)匹配请求映射

  2. @RequestMapping注解的method属性是一个RequestMethod类型的数组,表示该请求映射能够匹配多种请求方式的请求

  3. 若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错405:Request method ‘POST’ not supported

<a th:href="@{/test}">测试@RequestMapping的value属性-->/test</a><br>
<form th:action="@{/test}" method="post">
    <input type="submit">
</form>
@RequestMapping(
        value = {"/testRequestMapping", "/test"},
        method = {RequestMethod.GET, RequestMethod.POST}
)
public String testRequestMapping(){
    return "testReqMapping";
}

注:

  1. method属性的值也可以有多个,在html文件中使用的method只能为get或post,否则将会报错

  2. 对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解

    处理get请求的映射–>@GetMapping

    处理post请求的映射–>@PostMapping

    处理put请求的映射–>@PutMapping

    处理delete请求的映射–>@DeleteMapping

  3. 常用的请求方式有get,post,put,delete

    但是目前浏览器只支持getpost,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理

    若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到

5. params属性

  1. @RequestMapping注解的params属性通过请求的请求参数匹配请求映射

  2. @RequestMapping注解的params属性是一个字符串类型的数组,可以通过以下四种表达式设置请求参数和请求映射的匹配关系

    “param”:要求请求映射所匹配的请求必须携带param请求参数

    “!param”:要求请求映射所匹配的请求必须不能携带param请求参数

    “param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value

    “param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value

<a th:href="@{/test(username='admin',password=123456)">测试@RequestMapping的params属性-->/test</a><br>
@RequestMapping(
        value = {"/testRequestMapping", "/test"}
        ,method = {RequestMethod.GET, RequestMethod.POST}
        ,params = {"username","password!=123456"}
)
public String testRequestMapping(){
    return "testReqMapping";
}

注:

  1. params属性的值也可以有多个,它们之间是的关系,请求参数中必须所有的params属性值,上面的例子需要同时携带username和password两个,且password不能为123456,才能成功跳转。
  2. 上面的请求参数示例:http://localhost:8086/springMV/test?username=aaa&password=1234
  3. 若当前请求满足@RequestMapping注解的value和method属性,但是不满足params属性,此时页面回报错400:Parameter conditions “username, password!=123456” not met for actual request parameters: username={admin}, password={123456}

6. SpringMVC支持ant风格的路径

  1. ?:表示任意的单个字符

  2. *:表示任意的0个或多个字符

  3. **:表示任意的一层或多层目录

    注意:在使用**时,只能使用/**/xxx的方式
    示例:

// @RequestMapping("/a?a/testAnt")
// @RequestMapping("/a*a/testAnt")
@RequestMapping("/**/testAnt")
public String testAnt() {
    return "testReqMapping";
}
<a th:href="@{axa/testAnt}">测试@RequestMapping可以匹配Ant风格的路径-->使用?</a><br>
<a th:href="@{/ayyya/testAnt}">测试@RequestMapping可以匹配Ant风格的路径-->使用*</a><br>
<a th:href="@{/a/a/a/testAnt}">测试@RequestMapping可以匹配Ant风格的路径-->使用**</a><br>

7. SpringMVC支持路径中的占位符(重点)

  1. 原始方式:/deleteUser?id=1

  2. rest方式:/deleteUser/1

  3. SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,再通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参

@RequestMapping("/testPath/{id}/{username}")
public String testPath(@PathVariable("id") Integer id, @PathVariable("username") String username) {
    System.out.println("id:" + id + ",username:" + username);
    return "testReqMapping";
}
<a th:href="@{/testPath/1/admin}">测试@RequestMapping支持路径中的占位符-->testPath</a><br>

请求示例:http://localhost:8086/springMVC/testPath/1/admin,后面两个参数必须携带

三、SpringMVC获取请求参数

1. 通过ServletAPI获取

将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象(不推荐

@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    System.out.println("username:"+username+",password:"+password);
    return "testReqMapping";
}

2. 通过控制器方法的形参获取请求参数

在控制器方法的形参位置,设置和请求参数同名的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参(推荐

<a th:href="@{/testParam(username='admin',password=123456)}">测试获取请求参数-->/testParam</a><br>
@RequestMapping("/testParam")
public String testParam(String username, String password){
    System.out.println("username:"+username+",password:"+password);
    return "testReqMapping";
}

注:

  1. 若请求所传输的请求参数中有多个同名的请求参数,此时可以在控制器方法的形参中设置字符串数组或者字符串类型的形参接收此请求参数
  2. 若使用字符串数组类型的形参,此参数的数组中包含了每一个数据
  3. 若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果

3. @RequestParam

  1. @RequestParam是将请求参数和控制器方法的形参创建映射关系

  2. @RequestParam注解一共有三个属性:

    value:指定为形参赋值的请求参数的参数名

    required:设置是否必须传输此请求参数,默认值为true。
    defaultValue:设置默认值。不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为""时,则使用默认值为形参赋值(此属性常用

  3. 若required属性设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter ‘xxx’ is not present;若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null

4. @RequestHeader

  1. @RequestHeader是将请求头信息和控制器方法的形参创建映射关系

  2. @RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

5. @CookieValue

  1. @CookieValue是将cookie数据和控制器方法的形参创建映射关系,以获取Cookie的值

  2. @CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

6. 通过POJO获取请求参数

可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值
示例:

<form th:action="@{/testpojo}" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    性别:<input type="radio" name="sex" value=""><input type="radio" name="sex" value=""><br>
    年龄:<input type="text" name="age"><br>
    邮箱:<input type="text" name="email"><br>
    <input type="submit">
</form>
@RequestMapping("/testpojo")
public String testPOJO(User user){
    System.out.println(user);
    return "testReqMapping";
}

//最终结果-->User{id=null, username='张三', password='123', age=23, sex='男', email='123@qq.com'}

7. 解决获取请求参数的乱码问题

解决获取请求参数的乱码问题,可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册

<!--配置springMVC的编码过滤器-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注:

SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效。

四、域对象共享数据

四大域对象:

  1. pageContext (PageContextImpl 类) :当前 jsp 页面范围内有效,由于 jsp 已经过时,在 SpringMVC 中不加以使用

  2. request (HttpServletRequest 类) :一次请求内有效

  3. session (HttpSession 类):一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)

    钝化:当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下,这个过程叫做Session 的钝化。

    活化:当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化。

    注:钝化与活化实际上就是session的序列化与反序列化。

  4. application (ServletContext 类) :整个 web 工程(应用)范围内都有效(只要 web 工程不停止,数据都在),在服务器启动时创建,关闭时销毁。由于范围太大也少用。

域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。

虽然四个域对象都可以存取数据,但在使用上它们是有优先顺序的。

四个域在使用的时候,优先顺序是,他们从小到大的范围的顺序。:
pageContext ====>>> request ====>>> session ====>>> application

1. 使用ServletAPI向request域对象共享数据(不推荐)

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
    request.setAttribute("testScope", "hello,servletAPI");
    return "success";
}

2. 使用ModelAndView向request域对象共享数据

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
    /**
     * ModelAndView有Model和View的功能
     * Model主要用于向请求域共享数据
     * View主要用于设置视图,实现页面跳转
     */
    ModelAndView mav = new ModelAndView();
    //向请求域共享数据
    mav.addObject("testScope", "hello,ModelAndView");
    //设置视图,实现页面跳转
    mav.setViewName("success");
    return mav;
}

3. 使用Model向request域对象共享数据

@RequestMapping("/testModel")
public String testModel(Model model){
    model.addAttribute("testScope", "hello,Model");
    return "success";
}

4. 使用map向request域对象共享数据

@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
    map.put("testScope", "hello,Map");
    return "success";
}

5. 使用ModelMap向request域对象共享数据

@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
    modelMap.addAttribute("testScope", "hello,ModelMap");
    return "success";
}

6. 向session域共享数据

@RequestMapping("/testSession")
public String testSession(HttpSession session){
    session.setAttribute("testSessionScope", "hello,session");
    return "success";
}

7. 向application域共享数据

@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
	ServletContext application = session.getServletContext();
    application.setAttribute("testApplicationScope", "hello,application");
    return "success";
}

五、SpringMVC的视图

SpringMVC中的视图是view接口,视图的作用是渲染数据,将Model中的数据展示给用户。
SpringMVC视图种类有多种,默认有转发视图和重定向视图
若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView

1. ThymeleafView

当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转

@RequestMapping("/testHello")
public String testHello(){
    return "hello"; //没有任何的前后缀
}

2. 转发视图

SpringMVC中默认的转发视图是InternalResourceView

SpringMVC中创建转发视图的情况

当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"forward:"去掉,剩余部分作为最终路径通过转发的方式实现跳转
例如:forward:/testThymeleaf

@RequestMapping("/testForward")
public String testForward(){
    return "forward:/testThymeleaf";
}

3. 重定向视图

SpringMVC中默认的重定向视图是RedirectView

当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
例如redirect:/testThymeleaf

@RequestMapping("/testRedirect")
public String testRedirect(){
    return "redirect:/testThymeleaf";
}

注:

重定向视图在解析时,会先将redirect:前缀去掉,然后会判断剩余部分是否以 / 开头,若是则会自动拼接上下文路径。

4. 转发和重定向的区别

  1. 地址栏
    转发:不变,不会显示出转向的地址
    重定向:会显示转向之后的地址
    上面2转发视图和3重定向视图的结果,请求地址示例:
    转发:http://localhost:8086/springMVC03/testForward
    重定向:http://localhost:8086/springMVC03/testThymeleaf

  2. 请求
    转发:一次请求(可理解为直接http://localhost:8086/springMVC03/testForward
    重定向:至少提交了两次请求(我的理解是http://localhost:8086/springMVC03/testRedirect——>>http://localhost:8086/springMVC03/testForward

  3. 数据
    转发:对request对象的信息不会丢失,因此可以在多个页面交互过程中实现请求数据的共享
    重定向:request信息将丢失

  4. 原理
    转发:是在服务器内部控制权的转移,是由服务器区请求,客户端并不知道是怎样转移的,因此客户端浏览器的地址不会显示出转向的地址。
    重定向:是服务器告诉了客户端要转向哪个地址,客户端再自己去请求转向的地址,因此会显示转向后的地址,也可以理解浏览器至少进行了两次的访问请求。

5. 视图控制器view-controller

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示

<!--
	path:设置处理的请求地址
	view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>
<!--开启mvc注解驱动-->
<mvc:annotation-driven />

注:

当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签

六、RESTful

1. RESTful简介

REST:Representational State Transfer,表现层资源状态转移。

  1. 资源
    资源是一种看待服务器的方式,即将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。
  2. 资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。
  3. 状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

2. 实现

具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。

它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。

操作传统方式RESTful风格
查询操作getUserById?id=1user/1–>get请求方式
保存操作saveUseruser–>post请求方式
删除操作deleteUser?id=1user/1–>delete请求方式
更新操作updateUseruser–>put请求方式

3. HiddenHttpMethodFilter

由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?

SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求

HiddenHttpMethodFilter 处理put和delete请求的条件:

a)当前请求的请求方式必须为post

b)当前请求必须传输请求参数_method

满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_method的值才是最终的请求方式

在web.xml中注册HiddenHttpMethodFilter

<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注:
目前为止,SpringMVC中提供了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter,不然中文依旧乱码。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值