SpringMVC学习(一)之入门

一、三层架构和MVC

三层架构

1、开发服务器端程序,一般都基于两种形式,一种C/S架构(客户端/服务器)程序,一种B/S架构(浏览器/服务器)程序

2、使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构

3、三层架构
  表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
  业务层:处理具体的业务逻辑的
  持久层:用来操作数据库的

MVC模型

1、MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
2、Model:数据模型,JavaBean的类,用来进行数据封装。
3、View:指JSP、HTML用来展示数据给用户
4、Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。
在这里插入图片描述

二、SpringMVC的入门案例

项目目录如下:

在这里插入图片描述
1、Maven,web工程,pom.xml导入坐标

<properties>
  <!-- 版本锁定 -->
  <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

2、web.xml中的配置

<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>
    <!--配置 servlet 的对象的创建时间点:应用加载时创建。
    表示servlet被加载的先后顺序

    如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,
    值越小,servlet的优先级越高,就越先被加载。
    值相同时,容器就会自己选择顺序来加载。-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

其中相关配置说明:
<servlet>标签中
1、配置前端控制器DispatcherServlet 。
2、servlet加载全局初始化参数springmvc.xml,继而springmvc.xml中的配置能生效。
3、启动服务器即可使<servlet>中的配置生效:创建DispatcherServlet对象,加载springmvc.xml配置文件。

<servlet-mapping>标签 中
1、使<servlet>被请求到。
2、url-pattern中/是,让所有请求都被serlvet拦截到,继而走前端控制器。

3、springmvc.xml中的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.itheima" />
<!--视图解析器对象-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="prefix" value="/WEB-INF/pages/" />
   <property name="suffix" value=".jsp"/>
</bean>

<!--开启SpringMVC框架注解的支持-->
<mvc:annotation-driven />
</beans>

其中相关配置说明:
1、component-scan开启注解扫描,使spring能识别类中的@Controller等注解,将类交给IOC容器来管理。
2、配置视图解析器InternalResourceViewResolver,Controller中有return的值,如"success"。即为返回success.jsp这个页面。也需要使用配置来使springmvc框架知道在哪儿。这里需要使用<property>标签配置前缀和后缀。
3、开启springmvc框架注解支持,使springmvc相关注解能被支持。

<mvc: annotation-driven/>说明:
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用 <mvc: annotation-driven> 自动加载RequestMappingHandlerMapping (处理映射器) 和RequestMappingHandlerAdapter ( 处理适配器 ) , 可 用 在 SpringMVC.xml 配置文件中使用<mvc: annotation-driven>替代注解处理器和适配器的配置。

4、编写index.jsp、success.jsp和HelloController控制器类、启动Tomcat

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门程序</h3>
    <a href="hello">入门程序</a>
</body>
</html>

HelloController

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

@Controller
@RequestMapping(path = "user")
public class HelloController {

    /**
     * 入门案例
     *
     * @return
     */
    @RequestMapping(path = "/hello")
    public String sayHello() {
        System.out.println("Hello StringMVC");
        return "success";
    }

    /**
     * RequestMapping注解
     *
     * @return
     */
    @RequestMapping(path = "testRequestMapping")
    public String testRequestMapping() {
        System.out.println("测试RequsetMapping");
        return "success";
    }
}

在WEB-INF文件夹下创建pages文件夹,并创建和编写success.jsp的成功界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门成功</h3>
</body>
</html>

部署到Tomcat服务器上,进行测试即可。


入门案例的执行过程分析

在这里插入图片描述

1、入门案例的执行流程

1、当启动Tomcat服务器的时候,先去找web.xml文件,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象(前端控制器),参数初始化,就会加载springmvc.xml配置文件。
2、找springmvc.xml文件,开启了注解扫描,那么HelloController对象就会被创建。
3、从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据@RequestMapping注解配置的path的值,找到执行的具体方法。
4、根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件。
5、Tomcat服务器渲染页面,做出响应。

2、SpringMVC官方提供图形

在这里插入图片描述

3、入门案例中的组件分析
  1. 前端控制器(DispatcherServlet):用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
  2. 处理器映射器(HandlerMapping):HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  3. 处理器(Handler):它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
  4. 处理器适配器(HandlAdapter):通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
  5. 视图解析器(View Resolver):View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
  6. 视图(View):一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户。

三、RequestMapping注解

1、RequestMapping注解的作用:建立请求URL和处理方法之间的对应关系

2、RequestMapping注解可以作用在方法和类上
  作用在类上:第一级的访问目录,此处不写的话,就相当于应用的根目录。写的话需要以/开头。
  作用在方法上:第二级的访问目录
如:
在这里插入图片描述
那么要请求testRequestMapping的方法,请求路径就得写user/testRequestMapping 才能访问。
即:
在这里插入图片描述
细节:请求路径可以不编写 / 表示从应用的根目录开始
细节:${ pageContext.request.contextPath }也可以省略不写,但是请求路径上不能写 /
!!!如果请求路径为/user/testRequestMapping,那么访问的时候就不是localhost:8080/项目名称/user/testRequestMapping,而是localhost:8080/user/testRequestMapping,这种就不是从应用的根目录开始,会报404的错误

3、RequestMapping的属性
 path: 指定请求路径的url
 value: value属性和path属性是一样的
 method: 指定该方法的请求方式(枚举类型,直接类名.属性
 如:@RequestMapping(value="/saveAccount",method=RequestMethod.POST)
 params: 指定限制请求参数的条件
 如:params = {“accountName”},表示请求参数必须有 accountName
 headers: 发送的请求中必须包含的请求头
 
注意: 以上四个属性只要出现 2 个或以上时,他们的关系是与的关系。 即都要满足才能请求成功。

四、请求参数的绑定

1、请求参数的绑定说明

1、绑定机制

  • 表单提交的数据都是k=v格式的 username=haha&password=123
  • SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
  • 要求:提交表单的name和参数的名称是相同的

例如:

<a href="account/findAccount?accountId=10">查询账户</a>
href中请求参数是:
	accountId=10
/**
 * 查询账户
 * @return
*/
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
	System.out.println("查询了账户。。。。"+accountId);
	return "success";
}

运行结果:
在这里插入图片描述
即,当你方法的参数名称和请求参数的名称一样时,mvc框架就会自动将他们绑定在一起,也就是将请求参数的值赋给方法参数,方法内调用即可使用。

2、支持的数据类型

  • 基本数据类型和字符串类型
  • 实体类型(JavaBean)
  • 集合数据类型(List、map集合等)

SpringMVC 绑定请求参数是自动实现的,但是要想使用,必须遵循使用要求。

2、绑定的注意事项
  • 基本数据类型和字符串类型(案例:上面的示例)
      提交表单的name和参数的名称是相同的
      区分大小写
  • 实体类型(JavaBean)
      提交表单的name和JavaBean中的属性名称需要一致,因为这样才能找到JavaBean中属性对应的set方法,进行存储。
      如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性
      例如:address.name

案例:将表单提交的请求参数封装到JavaBean类中

实体类Account
在这里插入图片描述
实体类User
在这里插入图片描述
表单请求
在这里插入图片描述
Controller中的方法
在这里插入图片描述
运行结果:
在这里插入图片描述

  • 给集合属性数据封装
    JSP页面编写方式:
      List类型:list[0].属性
      Map<key,value>类型:map[key].属性

案例:
Account添加集合类型属性,并生成相应的get/set方法,重新生成toString方法

 private List<User> list;
 private Map<String,User> map;

form表单
在这里插入图片描述
运行结果:
在这里插入图片描述

五、请求参数中文乱码的解决

如果原生的Servlet,我们会使用request.setCharacterEncoding("utf-8")去解决,但是这样每个servlet都要写这句,很麻烦。
所以SpringMVC给我们提供了一种过滤器CharacterEncodingFilter。
即:任何请求都会经过过滤器,都会被过滤器拦截。如果被过滤器拦到就会帮你解决中文乱码。
在web.xml中配置过滤器

<!--配置解决中文乱码的过滤器
    注意:过滤器要配在servlet前面
-->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--指定UTF-8字符集-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

六、自定义类型转换器

1、表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明SpringMVC框架内部会默认进行数据类型转换。
在这里插入图片描述
2、如果想自定义数据类型转换,可以实现Converter的接口
  1、自定义类型转换器

/**
 * 把字符串转换日期
 */
public class StringToDateConverter implements Converter<String, Date> {
    /**
     * String s  传入进来字符串
     * @param s
     * @return
     */
    @Override
    public Date convert(String s) {
        //判断
        if (s == null){
            throw new RuntimeException("请您传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        //把字符串转换日期
        try {
           return df.parse(s);
        } catch (Exception e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}

2、注册自定义类型转换器,在springmvc.xml配置文件中编写配置

 <!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.itheima.utils.StringToDateConverter" />
        </set>
    </property>
 </bean>
 <!--开启SpringMVC框架注解的支持-->
 <!--conversion-service  将类型转换器配置生效 -->
 <mvc:annotation-driven conversion-service="conversionService"/>

这样子日期格式为2000-11-11的字符串也可以转换为Date类型了
运行结果如下:
在这里插入图片描述

七、在控制器中使用原生的ServletAPI对象

只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象
然后就可以按照需求,进行操作了。
如:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值