springmvc入门与参数绑定

学习目标

  • 能够描述springmvc框架

  • 能够搭建springmvc入门案例环境

  • 能够说出springmvc入门案例执行流程

  • 能够说出springmvc中常用的组件

  • 掌握@RequestMapping注解

  • 掌握springmvc中参数绑定

springmvc基本概念

关于三层架构和MVC

三层架构

我们的开发架构一般都是基于两种形式。一种是 C/S架构,也就是客户端/服务器;另一种是 B/S 架构,也就是浏览器/服务器。在 JavaEE开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S架构中,系统标准的三层架构包括:表现层、业务层、持久层。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。

三层架构中,每一层各司其职,接下来我们就说说每层都负责哪些方面:

层:介绍
表现层表现层指的是web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用 http协议请求web 层, web 需要接收 http 请求,完成 http 响应。表现层包括展示层和控制层:展示层负责结果的展示,控制层负责接收请求。表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。表现层的设计一般都使用 MVC 模型。( MVC 是表现层的设计模型,和其他层没有关系
业务层:业务层指的是 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。 web 层依赖业务层,但是业务层不依赖 web 层。业务层在业务处理时可能会依赖持久层,如果要对数据持久化保证事务一致性。业务层还需要事务,事务应该放到业务层来控制
持久层:持久层指的是 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。

MVC模型

MVC 全名是 Model View Controller,是**模型(model)-视图(view)-控制器(controller)**的缩写,是一种用于设计创建Web 应用程序表现层的模式。 MVC 中每个部分各司其职:

模型介绍
Model(模型):通常指的就是我们的数据模型。作用一般情况下用于封装数据
View(视图):通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。通常视图是依据模型数据创建的。
Controller(控制器):是应用程序中处理用户交互的部分。 它相对于前两个不是很好理解,这里举个例子:我们要保存一个用户的信息,该用户信息中包含了姓名,性别,年龄等等。这时候表单输入要求年龄必须是 1~100 之间的整数。姓名和性别不能为空。并且把数据填充到模型之中。此时除了 js 的校验之外,服务器端也应该有数据准确性的校验,那么校验就是控制器的该做的: 当校验失败后,由控制器负责把错误页面展示给使用者。 如果校验成功,由控制器负责把数据填充到模型,并且调用业务层实现完整的业务需求。

springmvc概述

springmvc是什么

springmvc 是一种基于 MVC 设计模型的请求驱动类型的轻量级 Web 框架, 属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。

spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 spring 可插入的 MVC架构,从而在使用 spring 进行 WEB 开发时,可以选择使用 spring的 spring MVC框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用), Struts2 等。

**springmvc 已经成为目前最主流的 MVC 框架之一, 从 Spring3.0 的发布, 就已全面超越Struts2,成为最优秀的 MVC 框架。**它通过一套注解,让一个简单的 Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。

springmvc在三层架构中的位置

在这里插入图片描述

springmvc优点

1清晰的角色划分各种控制器
2可扩展性好可以很容易扩展,虽然几乎不需要
3.与Spring 框架无缝集成这是其它web框架不具备的
4可适配性好通过 HandlerAdapter 可以支持任意的类作为处理器
5.可定制性好HandlerMapping、 ViewResolver 等能够非常简单的定制
6.单元测试方便利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试
7本地化、主题的解析的支持使我们更容易进行国际化和主题的切换
8.jsp标签库强大的 JSP 标签库,使 JSP 编写更容易

springmvc入门案例

入门程序

创建maven web项目

配置pom.xml,加入依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>springmvc</groupId>
    <artifactId>springmvc_qiuckstart</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>

        <!--spring 版本-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--spring webmvc 依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--servlet-api依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

    </dependencies>
</project>

springMVC.xml文件

说明:它是spring框架的核心配置文件。文件名称可以修改。spring的配置文件怎样创建,MVC的配置文件生成原理和Spring的生成原理一样。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QnXSQDp4-1582268516080)(media/1540638313057.png)]

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启组件扫描-->
    <context:component-scan base-package="controller"/>

</beans>

web.xml中配置前端控制器

说明:在web.xml文件中,需要配置一个springmvc框架提供的servlet(DispathcerServlet)。该servlet用于接收从浏览器发起的请求,它是springmvc框架的前端控制器(核心控制器)。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载springmvc主配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
        <!-- 配置web容器启动的时候加载前端控制器,数字越小,越快加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <!--配置简介中文乱码的过滤器-->
    <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>
    </filter>

    <!-- 配置请求url规则,说明:
           1.*.do,表示以.do结尾的请求进入前端控制器
           2./,表示所有请求都进入前端控制器
        -->
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

编写前端资源

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>hello,zhongzewei</h1>
</body>
</html>

编写controller

说明:springmvc框架中的controller,用于处理请求和响应页面。

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 控制器,处理请求的类
 *创建表现层的对象加入ioc容器
 */
@Controller
public class HelloController {

    /**
     * RequestMapping注解: 建立请求地址与后台处理请求的方法的映射关系。
     * 方法返回值:success  表示跳转(转发)地址的一部分,跳转后的页面的文件名称
     * 还缺少前缀和后缀(通过视图解析器处理)
     * 前缀:/
     * 后缀:.html
     * 完整请求路径:http://localhost:8080 + 前缀 + 方法返回值 + 后缀
     */
    @RequestMapping("/hello.do")
    public String hello() {
        System.out.println("开始执行/hello.do访问路径");
        return "hello";
    }
}

测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Dt5TdAo-1582268516080)(media/1540638928411.png)]

入门案例执行过程及原理分析

入门案例执行过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8HrCFDhj-1582268516081)(media/1539783309361.png)]

  • tomcat启动,加载web.xml文件,创建前端控制器DispatcherServlet对象。前端控制器加载springmvc.xml文件,创建spring容器,创建HelloController对象。

  • 客户端浏览器发起请求,请求到达前端控制器。DispatcherServlet接收到请求,将请求转发出去。根据请求的url进行匹配@RequestMapping配置内容。

  • 找到controlle中对应的方法,执行并返回ModelAndView(模型和视图)。

  • 根据ModelAndView中的视图名称,找到对应的页面(success.jsp)进行响应客户端浏览器

springmvc请求响应流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKacotY0-1582268516081)(media/ca328e6ed05b7207366cf314052cc379.png)]

springmvc三大组件

springmvc框架由一系列组件组成,其中比较有代表性的组件有:

  • 处理器映射器(HandlerMapping)

  • 处理器适配器(HandlerAdapter)

  • 视图解析器(ViewResolver)

处理器映射器(HandlerMapping)

作用:根据浏览器请求的url,找到处理器方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0YSFJq9w-1582268516081)(media/c6afb485f54a45920fa2462e1d4c5365.png)]

处理器适配器(HandlerAdapter)

作用:执行处理器方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ivUdXgIU-1582268516081)(media/1d733d646c390c3dda712a79b3c6b17f.png)]

细节:它是适配器设计模式的应用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sSkWEY1h-1582268516081)(media/54a72b56533d1b6302fd06f83c08d057.png)]

处理器映射器和适配器显示配置

在实际项目中,需要显示通过注解驱动方式配置处理器映射器和处理器适配器

    <!--注解驱动方式配置处理器映射器、处理器适配器,说明:
        1.导入mvc名称空间
        2.配置<mvc:annotation-driven/>
        3.它等于同时配置了RequestMappingHandlerMapping/RequestMappingHandlerAdapter
    -->
    <mvc:annotation-driven/>

视图解析器(ViewResolver)

作用:把逻辑视图(在处理器方法中设置的视图页面名称)解析成物理视图(在浏览器实际显示的页面)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-95826YCs-1582268516082)(media/9c6e891392b444db84ebca8303560cba.png)]

配置视图解析器

   <!--2.配置视图解析器(解析跳转的路径)-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--跳转路径的前缀-->
        <property name="prefix" value="/"/>
        <!--跳转路径的后缀名称-->
        <property name="suffix" value=".html"/>
    </bean>

springmvc框架原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u19IllQx-1582268516082)(media/1539784368740.png)]

@RequestMapping url注解

作用一:配置请求的url

   /**
     *
     * 作用一:配置请求的url
     * 属性:
     *      value:是一个数组,可以配置多个请求的url
     *      细节:"/"可以省略
     */
    @RequestMapping(value = {"add.do","add2.do"})
    public String add() {
        return "hello";
    }

限制http请求方法

@Controller
/**
 *
 * 限制http请求方法
 * 属性:
 *      RequestMapping放在类上,请求 URL 的第一级访问目录
 *      method:配置允许的http方法集合
 *      method = {RequestMethod.POST}:表示只允许post请求
 *      method = {RequestMethod.POST,RequestMethod.GET}:表示只允许post/get请求
 */
@RequestMapping(value = "/user",method = {RequestMethod.POST,RequestMethod.GET})
public class Controller1
    
-------------------------------------------------------------------------
/**
     * params = {"id=100"}  请求的参数,请求时候必须带id=100参数
     * method = RequestMethod.GET 表示当前方法只能处理post请求
     */
    @RequestMapping(value = "test1.do", params = {"id=100"}, method = RequestMethod.POST)
    public String test1() {
        System.out.println("执行test1");
        return "hello";
    }    
      

springmvc参数绑定[重要]

说明:在springmvc框架中,参数绑定指的是通过处理器(controller)方法的形参,获取请求的参数数据。

绑定的机制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v70GozWS-1582268516082)(media/1540639820691.png)]

支持的数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IXwNNTnF-1582268516082)(media/1540639867602.png)]

使用要求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sacVpNHG-1582268516083)(media/1540639928322.png)]

基本类型和String 类型作为参数

使用Integer类型

/**
 * 简单参数类型:使用Integer,接收请求的商品id参数数据
 * http://127.0.0.1:8080/param/queryItemById.do?id=1
 */
@RequestMapping("/queryItemById.do")
public String queryItemById(Model model, Integer id){

    // 打印参数数据
    System.out.println("商品Id参数值:"+id);

    // model封装模型数据
    /**
     * addAttribute方法,相当于ModelAndView的addObject方法
     */
    model.addAttribute("model","数据");

    return "item/edit";
}

注意事项:使用简单参数类型绑定参数,推荐使用简单类型的包装类型(Integer),不建议使用简单类型的基础类型(int)。原因是基础类型不能为null值,如果不传递会报异常。

使用String类型时:

/**
 * 请求参数名称必须与方法形参一样,否则不能正确封装数据。
 * 方法形参有多个时候,再访问时候可以不传入某些参数,结果为NULL
 */
@RequestMapping("test2.do")
public String test2(int id, String name) {
    System.out.println("执行test2");
    System.out.println("id=" + id + "---- name=" + name);
    return "hello";
}

POJO 类型作为参数

//访问/user/test3.do?id=100&name=jack
@RequestMapping("test3.do")
public String test3(User user) {
    System.out.println(user);
    return "hello";
}

POJO 类中包含集合类型参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vHIKw3oi-1582268516085)(media/1540640077169.png)]

@RequestMapping("test4.do")
public String test4(ComplexPo complexPo) {
    System.out.println(complexPo);
    return "hello";
}
<form action="/user/test4.do" method="get">
    ComplexPo的id<input type="text" name="id"><br>
    ComplexPo的name<input type="text" name="name"><br>
    <br>
    ComplexPo的user--user.id<input type="text" name="user.id"><br>
    ComplexPo的user--user-name<input type="text" name="user.name"><br>
    <br>
    ComplexPo的userList--userList[0].id<input type="text" name="userList[0].id"><br>
    ComplexPo的userList--userList[0].name<input type="text" name="userList[0].name"><br>
    <br>
    ComplexPo的userList--userList[1].id<input type="text" name="userList[1].id"><br>
    ComplexPo的userList--userList[1].name<input type="text" name="userList[1].name"><br>
    <br>
    ComplexPo的userHashMap--userHashMap['one'].id<input type="text" name="userHashMap['one'].id"><br>
    ComplexPo的userHashMap--userHashMap['one'].name<input type="text" name="userHashMap['one'].name"><br>
    ComplexPo的userHashMap--userHashMap['two'].id<input type="text" name="userHashMap['two'].id"><br>
    ComplexPo的userHashMap--userHashMap['two'].name<input type="text" name="userHashMap['two'].name"><br>
    <input type="submit">
</form>

请求参数乱码问题

**乱码的原因是tomcat服务器的默认字符集编码是ISO-8859-1,在post方法中不支持中文。**
<!--配置简介中文乱码的过滤器-->
<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>
</filter>

RequestParam 注解实现参数绑定

/**
 * @RequestParam 注解[建立请求参数与方法形参的映射关系]
 * 1.因为请求参数与方法形参不一致,所以要使用@RequestParam解决
 * 2.注解属性
 *   value 对应请求参数名称
 *   required = true 请求时候必须要带参数,否则报错(400 – Bad Request)
 *   defaultValue 指定默认值,如果请求时候没有带该参数,使用默认值。
 */
@RequestMapping("test10.do")
public String test10(@RequestParam(value = "name",required = false) String userxxxname)  {
    System.out.println(userxxxname);
    return "hello";
}

自定义类型转换器

页面提交的数据,能否自动转换为Date类型呢?

第一步:实现Converter接口(转换器类)

package utils;

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class String2DateConvert implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        try {
            // 判断
            if (StringUtils.isEmpty(source)) {
                return null;
            }
            // 转换
            return new SimpleDateFormat("yyyy-MM-dd").parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

}

第二步:配置类型转换器工厂(ConversionServiceFactoryBean)

<!--类型转换器工厂配置(ConversionServiceFactoryBean)-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="utils.String2DateConvert"/>
        </set>
    </property>
</bean>

第三步:springmvc中,指定类型转换器工厂

<!--springMVC注解中,指定类型转换器工厂-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>

其他支持的参数类型

HttpServletRequest

作用:通过request,获取请求的参数数据。

HttpServletResponse

作用:通过response,执行响应。

HttpSession

作用:通过session,获取和保存会话域数据。

@RequestMapping("test6.do")
public void test6(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    String id = request.getParameter("id");
    System.out.println("request的id值是"+id);
    String jSESSIONID = (String) session.getAttribute("JSESSIONID");
    System.out.println("session的值是"+jSESSIONID);
    response.getWriter().write("test6.do");
}

Model/ModelMap

说明:

  1. Model是一个接口,是模型,用于封装响应的模型数据

  2. ModelMap是实现类,使用Model和使用ModelMap,效果是一样的

  3. 使用Model封装响应的模型数据,就可以不使用ModelAndView,页面视图可以使用字符串
    响应。

/**
 * 使用Model封装响应的模型数据,使用字符串String响应页面视图
 */
@RequestMapping("/queryItemById.do")
public String queryItemById(Model model, HttpServletRequest request){

    // 打印参数数据
    String id = request.getParameter("id");
    System.out.println("商品Id参数值:"+id);
    
    // model封装模型数据
    /**
     * addAttribute方法,相当于ModelAndView的addObject方法
     */
    model.addAttribute("model","数据");

    return "item/edit";
}

消息头相关的两个注解【了解】

@RequestHeader注解

说明:@RequestHeader注解可以获取http请求的请求头信息。比如User-Agent,Referer等。

/**
 *  作用:设置请求的参数名称,与处理器方法形参名称匹配
 *  属性:
 *      value:设置请求的参数名称
 */
@RequestMapping("test7.do")
//求请求头中host对应的值
public String test7(@RequestHeader("host") String hostvalue)  {
    System.out.println(hostvalue);
   return "hello";
}

@CookieValue注解

说明:@CookieValue注解,可以获取指定cookie名称的cookie值。

@RequestMapping("test8.do")
public String test8(@CookieValue("JSESSIONID") String sessionvalue)  {
    System.out.println(sessionvalue);
    return "hello";
}

@RequestBody

作用:
用于获取请求体内容。 直接使用得到是 key=value&key=value…结构的数据。 get 请求方式不适用。

属性:
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false, get 请求得到是 null。

/**
 * 1.获取请求体内容,默认必须是post提交;否则报错。
 * 2.required=false 表示如果是get提交,不会报错。
 */
@RequestMapping("test9.do")
public String test9(@RequestBody(required = false) String requestbody) {
    System.out.println(requestbody);
    return "hello";
}

小结:

参数绑定常用注解

  1. @Controller声明处理器类
  2. @RequestMapping配置映射路径
  3. @RequestParam绑定单个请求参数值;
  4. @PathVariable绑定URI模板变量值;
  5. @CookieValue绑定Cookie数据值
  6. @RequestHeader绑定请求头数据;
  7. @ModelValue绑定参数到命令对象;
  8. @SessionAttributes绑定命令对象到session;
  9. @RequestBody绑定请求的内容区数据并能进行自动类型转换等。
  10. @RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的文件等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值