SSM框架之SpringMVC初识(一)

第一章 SpringMVC的基本概念

1. 概述

SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring FrameWork的后续产品,已经融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全功能模块。使用Spring可插入的MVC架构,从而在使用Spring进行Web开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架。
SpringMVC已经成为目前最主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,成为最优秀的MVC架构。
它通过一套经理,让一个简单的Java类成为处理请求的控制器,而无需实现任何接口。而且它还支持RESTful编程风格的请求。

2.SpringMVC的架构

  • M:model模型(javaBean)
    指的就是我们的数据模型,一般情况下用于数据封装。
  • V:View视图(jsp)
    指的是jsp或者html,作用一般就是展示数据的。通常视图是依据模型数据创建的。
  • C:Controller控制器(Servlet)
    应用程序中处理用户交互的部分。处理程序逻辑。


3.SpringMVC的优势

  • ①清晰的角色划分
    前端控制器:DispatcherServlet
    请求到处理器映射:HandlerMapping
    处理器适配器:HandlerAdapter
    视图解析器:ViewResolver
    处理器或页面控制器:Controller
    验证器:Validator
    命令对象:Command 请求参数绑定到的对象就叫命令对象
    表单对象:From Object 提供给表单展示和提交到的对象就叫做表单对象。
  • ②分工明确,而且拓展到相当灵活。可以很容易拓展,虽然不需要。
  • ③由于命令对象就是一个POJO,无需继承框架特定API,可以使用命令对象直接作为业务对象。
  • ④和Spring其他框架无缝集成,是其他web框架所不具备的。
  • ⑤可适配,通过HandlerAdapter可以支持任意的类作为处理器。
  • ⑥可定制,HandleMapping、ViewResolver等能够非常简单的定制。
  • ⑦功能强大的数据验证、格式化、绑定机制。
  • ⑧利用Spring提供的MOCK对象能够非常简单的进行web层单元测试。
  • ⑨本地化、主题的解析的支持,使我们更容易的进行国际化和主题的切换。
  • ⑩强大的JSP标签库,使JSP编写更容易。

4.SpringMVC和Struts2的优劣分析

共同点

  • 它们都是表现出框架,都是基于MVC模型编写的。
  • 它们的底层都离不开原始的ServletAPI。
  • 它们处理请求的机制都是一个核心控制器。
    区别
  • SpringMVC的入口是Servlet,而Struts2是Filter
  • SpringMVC是基于方法设计的,而Struts2是基于类,Struts2每次执行都会创建一个动作类,所以SpringMVC会比Struts2快些。
  • SpringMVC使用更加简洁,同时还支持JSR303,处理ajax的请求更方便。
  • Struts2的OGNL表达式使页面的开发效率相比Spring MVC更高些,但执行效率并没有JSTL提升,尤其是struts2的表单标签,远没有html执行效率高。

第二章 SpringMVC的入门

1. 目录结构

2.项目中maven依赖

<?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>com.seapp</groupId>
  <artifactId>springMVC-start</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>springMVC-start Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <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>


    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>springMVC-start</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

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/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--  开启注解扫描  -->
    <context:component-scan base-package="com.seapp"></context:component-scan>
    <!--配置视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--视图文件的文件路径(前缀)-->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <!--文件名后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

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

3. web.xml中对SpringMVC控制器的配置

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

<!-- SpringMVC的前端控制器的配置 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--  配置机制Spring配置文件  -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

4.jsp文件的实现

<%--
  Created by IntelliJ IDEA.
  User: EDZ
  Date: 2020/7/30
  Time: 13:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门程序</h3>

    <a href="hello" >入门程序</a>
</body>
</html>


<%--
  Created by IntelliJ IDEA.
  User: EDZ
  Date: 2020/7/30
  Time: 14:48
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>成功页面</h3>
</body>
</html>

5.Controller的具体实现

package com.seapp.controller;

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

/**
 * @author seapp
 * @date 2020/7/30 14:41
 */
@Controller
public class HelloController {

   
    @RequestMapping(path = "/hello")
    public String sayHello(){
        System.out.println("hello springMVC");
        return "success";
    }
}

6. @RequestMapping详解

 /**
     * @RequestMapping 注解详解
     * 作用:
     *     用于建立请求URL和处理请求方式之间的对应关系
     * *****************
     * @Target({ElementType.METHOD, ElementType.TYPE}):
     *     可作用在方法上或类上,两者结合可实现(分模块)。
     * *****************
     *  @AliasFor("path")
     *    String[] value() default {};
     *  @AliasFor("value")
     *    String[] path() default {};
     *    value和path的作用是指定请求的URL,两者作用一样。当只有一个属性的情况下,可省略。
     *  ***********
     *  RequestMethod[] method() default {};
     *  method:指定该方法的请求方式
     *      枚举:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
     *  ***********
     *  params :用于指定限制请求参数的条件,它支持简单的表达式。
     *    要求请求的key和value必须和配置的一模一样。
     *  *********
     *  header:发送的请求中必须包含的请求头
     * @return
     */

第三章 请求参数绑定

1.请求参数的绑定说明

绑定机制

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

支持的数据类型

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

2.基本数据类型和字符串类型

  • 提交表单的name和参数的名称是相同的。
  • 区分大小写

3.实体类型(JavaBean)

  • 提交表单的name和JavaBean中的属性名称需要一致。
  • 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例:user.name

4.给集合属性数据封装

5. 参数中文乱码的问题

  • web.xml文件中对过滤器的配置
<!--  配置解决中文乱码的过滤器-->
    <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>
    <filter-mapping>
      <filter-name>characterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

6. 特殊情况(自定义类型转换器)

  • Spring 提供的Converter类型转换基类
/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.convert.converter;

import org.springframework.lang.Nullable;

/**
 * A converter converts a source object of type {@code S} to a target of type {@code T}.
 *
 * <p>Implementations of this interface are thread-safe and can be shared.
 *
 * <p>Implementations may additionally implement {@link ConditionalConverter}.
 *
 * @author Keith Donald
 * @since 3.0
 * @param <S> the source type
 * @param <T> the target type
 */
@FunctionalInterface
public interface Converter<S, T> {

    /**
     * Convert the source object of type {@code S} to target type {@code T}.
     * @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
     * @return the converted object, which must be an instance of {@code T} (potentially {@code null})
     * @throws IllegalArgumentException if the source cannot be converted to the desired target type
     */
    @Nullable
    T convert(S source);

}

  • 自定义类型转换器的实现
package com.seapp.utils;

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

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

/**
 * @author seapp
 * @date 2020/8/1 16:15
 * 将字符串转换为日期
 *
 * 两个泛型:
 *      第一个泛型是源数据类型
 *      第二个泛型是目标数据类型
 */
public class StringToDateConverter implements Converter<String, Date> {

    /**
     *
     * @param source  传入进来的字符串
     * @return
     */
    @Override
    public Date convert(String source) {

        //非空判断
        if(source == null){
            throw new RuntimeException("请传入参数");
        }
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        
        try {
            //将数据转换为指定数据类型
            return dateFormat.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("数据类型转换失败");
        }
    }
}

  • 自定义类型转换器的注册
  <!-- 配置自定义类型转换器   -->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.seapp.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>

    <!-- 开启SpringMVC对注解框架的支持
        在SpringMVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。
        使用<mvc:annotation-driven/>自动加载RequestMappingHandlerMapping(处理映射器)和
        RequestMappingHandlerAdapter(处理适配器).
        可用在SpringMVC.xml配置文件中使用 <mvc:annotation-driven/>替代注解处理器和适配器的配置。
    -->
    <mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>

7.SpringMVC框架中获取Servlet原生的API

    /*  
     * 对Servlet原生Api的获取,只需要在方法上直接添加参数即可。
     * @return
     */
    @RequestMapping(path = "/hello")
    public String sayHello(HttpServletRequest request, HttpServletResponse response){
        System.out.println("hello springMVC");
        return "success";
    }

第四章 常用注解

1. @RequestParam

  • 作用:
    把请求中指定名称的参数给控制器中的形参赋值。
  • 属性:
    value:请求参数中的名称
    required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。

2. RequestBody

  • 作用:
    用于获取请求体的内容,直接使用得到的是key=value&key=value...结构的数据。
    get请求方式不适用
  • 属性:
    required:是否必须有请求体。默认值是true,当取值为true时,get请求方式会报错。如果取值为false,get请求得到的是null。

3. PathVaribale

  • 作用:
    用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是url占位符。
    url支持占位符是在spring3.0 之后加入的,是springMVC支持rest风格URL的一个重要标志。
  • 属性:
    value:用于指定url中占位符名称。
    required:是否必须提供占位符。

4. requestHeader

  • 作用:
    用于获取请求头信息
  • 属性:
    value:提供消息头名称
    required:是否必须有此消息头
  • :在实际开发中一般不咋用

5. CookieValue:

  • 作用:
    用于把指定cookie名称的值传入控制器方法参数
  • 属性:
    value:指定cookie的名称
    required:是否必须有此cookie

6. ModelAttribute

  • 作用:
    该注解是SpringMVC 4.3 版本以后新加入的,它可以用于修饰方法和参数。
    出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。
    出现在参数上,获取指定的参数给数据赋值。
  • 属性:
    value: 用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。
  • 应用场景:
    当表单提交的数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原有的数据。
  • 例:
    我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据时肯定没有此字段的内容,一单更新会把该字段内容置为null,此时就可以使用此注解解决问题。

7.SessionAttribute

-作用:
用于多次执行控制器方法间参数共享。

  • 属性:
    value:用于指定存入的属性名称
    type:用于指定存入的数据类型
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350