mvcday01

Spirng Mvc

三层架构介绍

咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
三层架构

  • 表现层:WEB层,用来和客户端进行数据交互的。
  • 业务层:处理公司具体的业务逻辑的。
  • 持久层:用来操作数据库的。

MVC设计模式介绍

MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。

  • Model:数据模型,JavaBean的类,用来进行数据封装。
  • View:指JSP、HTML用来展示数据给用户
  • Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等

MVC全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面 显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于 映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
Model-View-Controller 这种设计模式的最主要的目的就是解耦合又叫松耦合(不一样的功能,最好占用不同的模块,和别的模块之间的直接关系越少越好,越少越利于二次开发、扩展和维护)。

各模块职责:

Model 层与数据库直接交互,负责读写数据;
View 层直接与用户交互,负责向用户展示数据(使用不同的样式)或者接收用户的输入;
Controller 层则根据 View 层的用户输入调用Model 层的逻辑读写相关数据,并将数据选择适当的视图模板生成对应的 View 层展示效果。

总结

根据 MVC 模式开发的程序结构清晰易于维护,如果需要修改数据的展示样式时,只需要修改View 层对应的代码就可以了,比起不使用 MVC 的程序,在改动时被牵一发动全身恐惧所支配,实在是方便了不少。

SpringMVC简介

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等。

请求流程

在这里插入图片描述
在这里插入图片描述

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户

以上流程是以DispatcherServlet为核心轴,并且DispatcherServlet就是一个Servlet
在这里插入图片描述

XML方式

创建项目并导包

创建web项目,已经非常熟悉,不再多说
需要导入的包支持

<?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.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>demo</name>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
        <junit.version>5.7.0</junit.version>
        <spring.version>5.2.5.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!--Spring核心基础依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- 增加了切面 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.5</version>
        </dependency>

        <!-- spring jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--spring mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--日志相关-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!--测试相关-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.0</version>
            </plugin>
        </plugins>
    </build>
</project>
配置文件
web.xml
<?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_3_0.xsd"
         id="WebApp_ID" version="3.0">
    <display-name>SpringMVC_01_Basic</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <!-- 设置所有请求拦截到分发器
                         第一种 如果SpringMVC的配置文件,和web.xml在同一个目录
                         比如 MVC配置文件名字叫 basic-servlet.xml
                         只需要把servlet-name的值 设置为basic就可以,
                         但是 MVC配置文件的名字必须是xxx-servlet.xml的格式 -->
        <servlet-name>basic</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定配置文件-->
        <!-- <init-param> -->
        <!-- <param-name>contextConfigLocation</param-name> -->
        <!-- 可以放在任何地方 -->
        <!-- <param-value>/a/b/c/d/xxxxxxxxx.xml</param-value> -->
        <!-- 放在src下 -->
        <!-- <param-value>classpath:xxxxxxxxx.xml</param-value> -->
        <!-- </init-param> -->
      	<!-- 项目启动就会加载这个servlet -->
  			<load-on-startup>1</load-on-startup>	  
  	</servlet>
    <servlet-mapping>
        <servlet-name>basic</servlet-name>
        <url-pattern>/</url-pattern>
        <!--
                         /* 会拦截jsp文件
                         / 不会拦截jsp
         -->
    </servlet-mapping>
</web-app>
basic-servlet.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
                  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
    <!-- 使用XML进行映射
            MVC框架基本两个点
                              1 url怎么映射进去进行处理
                              2 处理完如何找到视图
    -->
    <!-- 处理映射器配置-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!-- 创建映射,配置映射器,name必须是 / 打头-->
    <bean name="/w" class="com.tledu.controller.XmlMappingController"/>

    <!-- 视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

控制器类

package com.tledu.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class XmlMappingController extends AbstractController {
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        System.out.println("Welcome~");
        return new ModelAndView("welcome");
    }
}
jsp页面

视图解析器这里,我们指定了文件的目录和后缀
当controller返回了welcome的时候 就会去找WEB-INF/jsp/welcome.jsp
需要创建对应的jsp

<%--
  Created by IntelliJ IDEA.
  User: cyrus
  Date: 2021/04/07
  Time: 0:44
  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>
    欢迎来到天亮教育
</body>
</html>
运行测试

运行web程序,浏览器输入
http://localhost:8080/SpringMVC_01_Basic/w

小结

1创建项目,引入依赖
2配置web.xml
因为现在,所有请求,我们都希望通过spring mvc进行管理
配置servlet
name
class:对应的路径(DispatchServlet)
配置了servletMapping
servlet-name: 对应到上面的名字
地址 /
3配置Spring
文件的位置要和web.xml同级
文件名字和servlet中servlet的名字对应上
servlet名字-servlet.xml
配置MappingHandle的实例

配置映射关系
配置 视图解析器
4实现Controller
extends AbstractController
实现一个抽象方法
返回一个ModelAndView

注解方式

配置文件

<?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"
         xmlns:mvc="http://www.springframework.org/schema/mvc"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
                  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
         <context:component-scan base-package="com.tledu.zrz.springmvc.controller"/>
         <mvc:annotation-driven />
         <!--视图解析器 -->
         <bean
                  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  <property name="prefix"value="/WEB-INF/jsp/"/>
                  <property name="suffix"value=".jsp"/>
         </bean>
</beans>
  1. 配置包扫描,需要能把controller放到spring容器管理
  2. 添加一个Controller类,并加上Controller注解
  3. 类上加@RequestMapping(""),配置地址和controller的映射关系
  4. 在方法上加@RequestMapping(""),配置地址和方法的映射关系
  5. 执行方法,并返回一个字符串,这个字符串就是view-name

常用注解

  1. @Controller
    

使用Controller注解之后,在方法上可以通过return的jsp或者html页面的名字,通过视图解析器,就能跳转到指定页面
如果没有Controller注解,这个类中的方法是不会被请求过去的
所对应的层也是controller层,表现层
2. @RestController
RestController注解相当于Controller和ResponseBody一起使用
这个类中的方法可以被请求过来,但是方法中无法jsp和html页面,视图解析器就不会起到作用,返回的内容就是return后面的内容
3. @RequestMapping
是Spring Web应用中最常用到的注解之一,这个注解会将http请求映射到MVC和Controller控制器的处理方法上
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
4. @RequestBody
@RequestBody 主要用于接收前端通过 请求体 传递给后端的JSON字符串中的数据
GET方式无请求体,所以使用@RequestBody的时候不能使用GET方式,而应该使用POST形式
5. @RequestParam
用于接收前端传递过来的url中的参数(key=value)的形式
主要用于接收前后端key不一致的时候,使用@RequestParm来指定获取
6. @PathVaraible
@PathVaraible主要用于获取url请求中的动态参数的

@RequestMapping(“/delete/{id}”)
public String delete(@PathVaraible(“id”) int id){}
当RequestMapping中需要动态传递过来参数的时候,需要通过@PathVaraible来接收
7. @ResponseBody
如果方法需要返回JSON或者XML或者自定义内容到页面中去,就需要再方法上加上ResponseBody,这个时候,返回的数据就会不被视图解析器所解析
8. SessionAttributes注解
用于多次执行控制器方法间的参数,可以通过value指定存入属性的名字
比如 :

package com.tledu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

@Controller
@RequestMapping(path="/hello")
@SessionAttributes(value= {"username","password","age"},types=
        {String.class,Integer.class})
public class HelloController {
    /**
     * 向session中存入值
     * @return
     */
    @RequestMapping(path="/save")
    public String save(Model model) {
        System.out.println("向session域中保存数据");
        model.addAttribute("username", "root");
        model.addAttribute("password", "123");
        model.addAttribute("age", 20);
        return "success";
    }
    /**
     * 从session中获取值
     * @return
     */
    @RequestMapping(path="/find")
    public String find(ModelMap modelMap) {
        String username = (String) modelMap.get("username");
        String password = (String) modelMap.get("password");
        Integer age = (Integer) modelMap.get("age");
        System.out.println(username + " : "+password +" : "+age);
        return "success";
    }
    /**
     * 清除值
     * @return
     */
    @RequestMapping(path="/delete")
    public String delete(SessionStatus status) {
        status.setComplete();
        return "success";
    }
}

控制器类和参数绑定

RequestMapping详解
RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系
equestMapping注解可以作用在方法和类上
  • 作用在类上:第一级的访问目录
  • 作用在方法上:第二级的访问目录
  • 细节:路径可以不编写 / 表示应用的根目录开始
  • 细节:${
    pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /
RequestMapping的属性

path 指定请求路径的url
value value属性和path属性是一样的
method 指定该方法的请求方式
GetMapping
PostMapping
PutMapping
DeleteMapping
params 指定限制请求参数的条件
headers 发送的请求中必须包含的请求头

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

2.1 支持的数据类型

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

提交表单的name和参数的名称是相同的
区分大小写
如果名称不相同可以通过@RequestParam(“user”),指定参数名字
如果参数是必传的@RequestParam(required = true)

实体类型(JavaBean)

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

给集合属性数据封装

表单提提交
list:多个同名属性设置list
获取通过json的方式进行提交
需要设置注解@RequestBody

请求参数中文乱码的解决
  1. 在web.xml中配置Spring提供的过滤器类
<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>
自定义类型转换器
  1. 表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换。
  2. 如果想自定义数据类型转换,可以实现Converter的接口
    1.自定义类型转换器
package com.tledu.spring_mvc_basic.utils;


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

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

public class StringToDateConverter implements Converter<String, Date> {

    @Override
    public Date convert(String source) {
        // 判断
        if(source == null) {
            throw new RuntimeException("参数不能为空");
        }
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 解析字符串
            Date date = df.parse(source);
            return date;
        } catch (Exception e) {
            throw new RuntimeException("类型转换错误");
        }
    }

}
  1. 注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!-- 注册自定义类型转换器 --> 
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters"> 
<set>
<bean class="cn.itcast.utils.StringToDateConverter"/> 
</set> 
</property> 
</bean> 
<!-- 开启Spring对MVC注解的支持 --> 
<mvc:annotation-driven conversion-service="conversionService"/>

json里日期参数格式化可以使用@JsonFormat(pattern = “yyyy/MM/dd”)注解进行配置

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

只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象
通过注入的方式也可以获取

参数绑定使用

5 为了方便向视图层传值,提供了 Model 专门向视图层传递数据
请求为 http://localhost:8080/SpringMVC_01_Basic/hello?username=root

         @RequestMapping("/hello")
         public String hello(String username,Model model) {
                  // 键值对,页面可以通过username获取对应的值
                  model.addAttribute("username", "Hello : "+username);
                  // 参数是值,页面需要根据值的类型的首字母小写获取
                  model.addAttribute(username);
                  // 如果 类名前两个字母都是大写,就不会把首字母转换为小写了
                  return "hello";
}
<body>
                  Hello~ <br>
                  ${username } <br>
                  ${string } 
</body>

6 多个Url映射到同一个方法上
请求为 http://localhost:8080/SpringMVC_01_Basic/hello?username=root

    @RequestMapping({"/hello","/h","/hi"})
         public String hello(String username,Model model) {
                  model.addAttribute("username", "Hello : "+username);
                  return "hello";
}

这时候/hello 和/h 以及 /hi 请求 都会来执行这个方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值