SpringMVC 学习日记(1)

SpringMVC 概述

Hadoop 弄炸了,再来学学 JAVAWEB 缓缓

SpringMVC 是什么

SpringMVC:是基于 spring 的一个框架,实际上就是 Spring 的一个模块,专门做 Web 开发的,可以理解为 Servlet 的一个升级。

Web 开发底层是 Servlet,框架是在 Servlet 基础长增加一些功能,让你做 Web 开发更方便。

SpringMVC 就是 Spring。Spring 是一个容器,ioc 能管理对象,使用 ,@Component

SpringMVC 能够创建对象,放入容器中(Spring MVC 容器),SpringMVC 容器中放的是控制器对象。

我们要做的就是使用 Controller 创建控制器对象,把对象放入到 springmvc 容器中,把创建的对象作为控制器使用。

这个控制器对象能接受用户的请求,显示处理结果,就当做是一个 Servlet 使用。

使用 @Controller 注解创建的是一个普通的类的对象,不是 Servlet,SpringMVC 赋予了控制器对象一些额外的功能。

Web 开发底层是 Servlet,SpringMVC 中有一个对象是 Servlet: DispatherServlet

DispatherServlet:负责接受用户的所有请求,用户把请求给了 DispatherServlet,之后 DispatherServlet 把请求转发给我们的 Controller 对象,最后是 Controller 对象来处理。

index.jsp -> DispatherServlet(Servlet) -> 转发,分配给 -> Controller 对象 (@Controller 注解创建的对象)

第一个 SpringMVC 程序

创建一个新工程

在这个新工程下创建一个 Maven 模块

在 pom.xml 下添加所需要的依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- servlet 依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- springmvc 依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
    </dependencies>

添加编译插件

    <build>
        <plugins>
            <!-- 编码和编译和JDK版本 -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

更改 web.xml 的版本

之后再重命名回 web.xml

发布项目到 tomcat

web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 声明,注册 springmvc 的核心对象 DispatcherServlet
        需要在 tomcat 服务器启动后,创建 DispatcherServlet 对象的实例
        因为 DispatcherServlet 在他的创建过程中,会同时创建 springmvc 容器对象
        读取 springmvc 的配置文件,把这个配置文件中的对象都创建好,当用户发起请求时
        就可以直接使用对象了

        Servlet 初始化会执行 init() 方法,DispatcherServlet 在 init() 中 {
            // 创建容器,读取配置文件
            WebApplicationContext ctx = new ClassPathXmlApplication("spingmvc.xml");
            // 把容器对象放入到 ServletContext 中
            getServletContext().setAttribute()

        }

        启动 tomcat 报错:读取这个文件 /WEB-INF/springmvc-servlet.xml
        springmvc 创建容器时,读取的配置文件默认是/WEB-INF/<servlet-name>-servlet.xml
    -->
    <servlet>


        <servlet-name>myweb</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <!-- 自定义springmvc读取的配置文件的位置-->
        <init-param>
            <!-- springmvc 配置文件的位置的属性 -->
            <param-name>contextConfigLocation</param-name>
            <!-- 指定自定义文件的位置 -->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>


        <!-- 在 tomcat 启动后创建 Servlet 对象
             load-on-start:表示 tomcat 启动后创建对象的顺序
             它的值是一个整数,数值越小,tomcat创建对象的时间越早
         -->


        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>myweb</servlet-name>
        <!--
        使用框架时,url-pattern 可以使用两种值
        1、使用扩展名的方式:语法 *.xxx, xxx 是自定义的扩展名,常用扩展名 *.do *.action *.mvc 等
           http://localhost:8080/myweb/some.do
        
        2、使用斜杠 "/"
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

创建 springmvc 配置文件

在 resources 文件夹下创建 springmvc 配置文件

项目结构

创建控制类

编写 index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <p>第一个spingmvc项目</p>
    <p><a href="some.do">发起some.do请求</a> </p>
</body>
</html>

控制类

package com.an.controller;

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

/**
 * @Controller:创建处理器对象,对象放在 springmvc 容器
 *
 * 位置:在类的上面
 *
 * 和 Spring 讲的 @Service ,@Componet
 */

@Controller
public class MyController {
	/*
	处理用户提交的请求,springmvc 中使用方法来处理
	方法是自定义的,可以有多种返回值,多种参数,方法自定义名称
	 */

	/**
	 * 准备使用 doSome 方法来处理 some.do 的请求
	 * @RequestMapping 请求映射,作用是把一个请求地址和一个方法绑定在一起
	 * 一个请求指定一个方法处理
	 * 属性:1、value 是一个 String,表示请求的 url 地址的(some.do)
	 *         value 值必须是惟一的,不能重复。在使用时,推荐地址以 "/"
	 *
	 * 位置:1、在方法上面,常用的
	 *      2、在类的上面
	 *
	 * 说明:使用 RequestMapping 修饰的方法叫做处理器方法或者控制器方法
	 * 使用 @RequestMapping 修饰的方法可以处理请求的,类似 Servlet 中的 doGet, doPost
	 * 返回值:ModelAndView 表示本次请求的处理结果
	 * Model:数据,请求处理完成后,要显示给用户的数据
	 * View:视图,比如 jsp 等等
	 */
	@RequestMapping(value="/some.do")
	public ModelAndView doSome() { // doGet() -> service 请求处理
		// 处理some.do请求了。相当于 Service 调用处理完成了
		ModelAndView mv = new ModelAndView();
		// 添加数据,框架在请求最后把数据放入到 request 作用域
		mv.addObject("msg","欢迎使用mvc");
		mv.addObject("fun","执行的是doSome方法");

		// 指定视图,指定视图的完整路径
		// 框架对视图执行的 forward 操作,request.getRequestDispatcher("/show.jsp").foward(...);
		mv.setViewName("/show.jsp");
		
		// 返回 mv
		return mv;
	}
}

创建 show.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>show.jsp从request作用域获取数据</h3> <br />
    <h3>msg:数据${msg}</h3> <br />
    <h3>fun:数据${fun}</h3>
</body>
</html>

开启组件扫描器

springmvc.xml

<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 声明组件扫描器 -->
    <context:component-scan base-package="com.an.controller" />

</beans>

项目执行结果

SpringMVC 请求的处理过程

  1. 发送 some.do

  2. tomcat(Web.xml-url-pattern 知道 *.do 的请求给DispatcherServlet)

  3. DispatcherServlet(根据 springmvc.xml 配置文件知道 some.do 对应 doSome() 方法)

  4. DispatcherServlet 把 some.do 转发给 MyController.doSome() 方法

  5. 框架执行 doSome() 把得到的 Model And View 进行处理,转发到 show.jsp

中央调度器 DispatcherServlet

1、负责创建 springMVC 容器对象,读取 xml 配置文件,创建文件中的 Controller 对象

2、负责接收用户的请求,分派给自定义的 Controller 对象

springMVC 创建过程源代码分析

1、tomcat 启动,创建容器的过程

通过 load-on-start 标签指定的 1,创建 DispatcherServlet 对象,

DispatcherServlet 它的父类是继承 HttpServlet 的,它是一个 servlet,在被创建时,会执行 init() 方法。在 init() 方法中

// 创建容器,读取配置文件
WebApplicationContext ctx = new ClassPathXmlApplication("spingmvc.xml");
// 把容器对象放入到 ServletContext 中
getServletContext().setAttribute()

上面创建容器的作用:创建 @Controller 注解所在类的对象,创建 MyController 对象。

这个对象放入到 springmvc 容器中,容器是 map,类似 map.put("mycontroller",MyController 对象)

2、请求的处理过程

  1. 执行 Servlet 的 service 方法

  2. 执行 service 方法中的 doDispatcher 方法,最终调用 MyController 对象中的方法

配置视图解析器

1、为了放置能直接访问 show.jsp

将 show.jsp 放入 WEB-INF 目录中

2、MyController 中 setViewName 更改为

mv.setViewName("/WEB-INF/view/show.jsp");

3、使用视图解析器解决重复路径问题

在 springmvc.xml 中添加

<!-- 声明 springmvc 框架中的视图解析器,帮助开发人员设置视图文件的路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 前缀:视图文件的路径 -->
    <property name="prefix" value="/WEB-INF/view/" />
    <!-- 后缀:视图文件的扩展名 -->
    <property name="suffix" value=".jsp" />
</bean>

4、简化后的 setViewName

// 当配置了视图解析器后,可以使用逻辑名称(文件名)来指定视图
// 框架会使用视图解析器的前缀 + 逻辑名称 + 后缀 组成完整路径,这就是字符串连接操作
mv.setViewName("show");

5、配置多个访问地址

@RequestMapping(value={"/some.do","/other.do"})

Spring MVC 注解式开发

@RequestMapping 放在类上面

/**
 * @RequestMapping
 * value: 所有请求地址的公共部分,模块名称
 * 位置:放在类的上面
 *
 */

@Controller
@RequestMapping(value="/user")
public class MyController {
	@RequestMapping(value={"/some.do","/first.do"})
	public ModelAndView doSome() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("msg","欢迎使用mvc");
		mv.addObject("fun","执行的是doSome方法");
		mv.setViewName("show");
		return mv;
	}
}

定义请求方式 Method 属性

@Controller
@RequestMapping(value = "/user")
public class MyController {
	/**
	 * @return
	 * @RequestMapping:请求映射 属性:method,请求的方式,它的值是 RequestMethod 类的枚举值
	 * 例如表示 get 请求方式,RequestMethod.GET, RequestMethod.POST,不使用规定的返回方式
	 * 返回 405
         */
	// 指定 some.do 使用 get 请求方式
	@RequestMapping(value = {"/some.do", "/first.do"}, method = RequestMethod.GET)
	public ModelAndView doSome() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("msg", "欢迎使用mvc");
		mv.addObject("fun", "执行的是doSome方法");
		mv.setViewName("show");
		return mv;
	}
}

处理器方法形参

处理器方法可以包含下面四种参数,这些参数会在系统调用时由系统自动赋值,程序员可以在方法内直接使用。

  • HttpServletRequest

  • HttpServletResponse

  • HttpSession

  • 请求中所携带的请求参数

获取request方法参数

/**
 * 逐个接收请求参数:
 * 要求:处理器方法(控制器)的形参名和请求中参数名必须一致
 * 同名的请求参数赋值给同名的形参
 *
 * 框架接收请求参数
 *
 * 1、使用 request 对象接收请求参数
 *      String strName = request.getParameter("name")
 *      String strAge = request.getParameter("age")
 * 2、springmvc 框架通过 DispatcherServlet 调用 MyController 的 doSome() 方法
 *    调用方法时,按名称对应,把接收的参数赋值给形参
 *    框架会提供类型转换的功能,能把 String 转为 int、long、float、double 等类型
 */
// 指定 some.do 使用 get 请求方式
@RequestMapping(value = {"/some.do", "/first.do"}, method = RequestMethod.POST)
public ModelAndView doSome(String name, int age) {
	ModelAndView mv = new ModelAndView();
	mv.addObject("myname",name);
	mv.addObject("myage",age);
	mv.setViewName("show");
	return mv;
}

接收用户提交参数-逐个接收

	/**
	 * 逐个接收请求参数:
	 * 要求:处理器方法(控制器)的形参名和请求中参数名必须一致
	 * 同名的请求参数赋值给同名的形参
	 *
	 * 框架接收请求参数
	 *
	 * 1、使用 request 对象接收请求参数
	 *      String strName = request.getParameter("name")
	 *      String strAge = request.getParameter("age")
	 * 2、springmvc 框架通过 DispatcherServlet 调用 MyController 的 doSome() 方法
	 *    调用方法时,按名称对应,把接收的参数赋值给形参
	 *    框架会提供类型转换的功能,能把 String 转为 int、long、float、double 等类型
	 *    400状态码是客户端错误,表示提交请求参数过程中,发生了问题
	 */
	// 指定 some.do 使用 get 请求方式
	@RequestMapping(value = {"/some.do", "/first.do"}, method = RequestMethod.POST)
	public ModelAndView doSome(String name, Integer age) {
		ModelAndView mv = new ModelAndView();
		mv.addObject("myname",name);
		mv.addObject("myage",age);
		mv.setViewName("show");
		return mv;
	}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <p>提交参数给 Controller</p>
    <form action="user/first.do" method="post">
        姓名:<input type="text" name="name"> <br />
        年龄:<input type="text" name="age"> <br />
        <input type="submit" value="提交参数">
    </form>
</body>
</html>

show.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>show.jsp从request作用域获取数据</h3> <br />
    <h3>myname:数据${myname}</h3> <br />
    <h3>myage:数据${myage}</h3>
</body>
</html>

结果

posted @ 2021-06-06 22:54  ans20xx  阅读(88)  评论(0编辑  收藏  举报