CGB2105第二阶段-三大框架之一SpringMVC

目录

一、SpringMVC框架

1、概述

2、MVC模型

3、工作原理--面试题

1)更具体一些的描述:

2)、主要操作器

4 SpringMVC 参数取值详情说明

4.1 Servlet

4.2 Servlet获取参数规则

4.3  对象方式

二、入门案例:展示汽车数据

1、需求

2、创建Module

3、创建启动类--Controller

4、创建资源--Model

4.1、创建Car类

 4.2、改造CarController

4.3、前后端关联,改造网页,在html网页超链接获取数据--View

三、利用SpringMVC解析请求参数

1、概述

2、浏览器提交请求数据的方式

3、get方式解析请求参数

四、SpringMVC常见问题解决

1、404-请求的url不存在

 2、500--请求的url未绑定参数

3、400-url 的请求和服务器需要的参数类型不同

五、restful风格解析请求参数

1、项目结构

 2、修改网页

3、修改car

4、修改CarController

5、测试

六、ajax提交请求数据

1、创建新的网页html,添加ajax代码

2、改造CarController类,加一个跨域的注解@CrossOrigin

3、测试

七、SpringMVC常用的注解


一、SpringMVC框架

1、概述

SpringMVC框架的核心作用:接收浏览器发来的请求,并给浏览器作出响应。

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。

使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一 般不用),Struts2(一般老项目使用)都有安全问题。

SpringMVC就是基于MVC设计模式来实现的。

我们的POJO就是Model层,我们的JSP就是视图层,我们的Controller就是控制层。

现在主流基于SSM三大框架开发都是在MVC上继续演化,又分为持久层DAO,业务层Servie,控制层Controller。持久层用来和数据库读写ORM,业务层用来处理复杂的业务逻辑,控制层用来处理MVC的控制。


2、MVC模型

通用的软件编程思想, 在MVC设计模式中认为, 任何软件都可以分三层

Model模型-存储、封装数据、

View视图-展示数据结果、

Controller控制层-接收请求、处理响应

代码分离结构清晰,各司其职,易于开发大型项目。

优点:MVC三部分相互独立,如果某一个模块发生变化,应该尽量做到不影响其他两个模块。提高代码的可读性,实现程序间的松耦合、提高代码复用性。

 性能:简单易用

3、工作原理--面试题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XH0fEJst-1623044111711)(RackMultipart20210607-4-13lyxac_html_e58ee630c0df1991.png)]

1)更具体一些的描述:

1、用户发送请求至前端控制器DispatcherServlet。

2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找类和方法),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4、DispatcherServlet调用HandlerAdapter处理器适配器。

5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

6、Controller执行完成返回ModelAndView。

7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

8、DispatcherServlet将ModelAndView传给ViewResolver视图解析器。

9、ViewResolver解析后返回具体View。

10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

11、DispatcherServlet最后再响应给用户。

2)、主要操作器

1.前端控制器:DispatcherServlet,用来接受请求分发请求,servlet是java与前端页面进行数据交互的一种机制
2.处理器映射器:HandlerMapping,用来根据url找具体的类里的具体方法
http://localhost:8080/abc/hi
@RequestMapping(“abc”)public class HelloBoot {@RequestMapping(“hi”) public String hello(){ } }
3.处理器适配器:HandlerAdapter,用来执行方法里的代码
4.视图解析器:ViewResolver,定位页面的路径
5.视图:View,用来展示数据

3、MVC三层结构:

4 SpringMVC 参数取值详情说明

4.1 Servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。Servlet的生命周期可以分为四个阶段,即装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段.
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

总结: Servlet是java与前端页面进行数据交互的一种机制
核心对象:
1. request对象 封装用户请求的参数/请求头/请求全部内容
2. response对象 封装用户响应信息

  

4.2 Servlet获取参数规则

controller层:

 /**
     * 注意事项: 如果后端服务器没有匹配的方法,也会报跨域错误.
     * URL:http://localhost:8090/getUserById?id=1&age=18
     * 参数: id=1
     * 返回值: User对象
     * servlet特点:
     *  1.获取的数据都是String类型
     */
    @GetMapping("/getUserById")
    public User getUserById(Integer id){
       //1.SpringMVC框架通过Servlet中request对象,根据参数名称获取值
        // String id = request.getParameter("age");
        //2.SpringMVC根据已知的数据类型 自动的实现数据转化
        return null;
    }



    /*@GetMapping("/getUserById")
    public User getUserById(HttpServletRequest request,
                            HttpServletResponse response){
        //1.参数获取 每个参数都需要手动获取
        String id = request.getParameter("id");
        String age = request.getParameter("age");

        //2.数据类型转化
        int intId = Integer.parseInt(id);
        System.out.println("根据ID查询数据库~~~~~");

        return null;
    }*/

4.3  对象方式

1)页面对象封装

在这里插入图片描述

 2)后端参数接收问题

 /**
     * URL: http://localhost:8090/getUserByUser
     * 参数: user对象的数据
     * 返回值: User
     */
    @GetMapping("/getUserByUser")
    public User getUserByUser(User user){
        //1.SpringMVC如果解析到参数是对象 先获取其中的Get方法
        // getId()/getName()......
        //2.将方法get去除首字母小写~~~id1111/name/age/sex
        //3.实例化一个User对象之后调用setxxx()方法实现赋值
        //4.最终方法中获取一个实例化的User对象
        //String id = request.getParameter("id");
        return user;
    }

二、入门案例:展示汽车数据

前提是在创建了Spring Boot工程下,再建SpringMVC的Module

1、需求

访问链接: http://localhost:8080/car/get

得到JSON数据: {"id":718,"name":"保时捷","type":"Cayman T","color":"红色","price":641000.0}

2、创建Module

在这里插入图片描述

 

 在这里插入图片描述

3、创建启动类--Controller

注意:

1)启动类只会在创建project工程时会自动生成启动类,而在创建module项目时不会自动创建启动类,需要手动创建启动类

2)创建module后java文件不能创建class时,右键mark derictory--》source root

3)停掉Oracle
步骤:此电脑--》右键管理--》右键服务和应用程序--》双击服务--》找到OracleXETNSListener右键属性--启动类型改为禁用

在这里插入图片描述

整体需要的两个包,三个类:

在这里插入图片描述

package cn.tedu.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;


@SpringBootApplication
@Controller
public class RunApp {
    public static void main(String[] args) {
        SpringApplication.run(RunApp.class);
    }
}

4、创建资源--Model

4.1、创建Car类

创建包:cn.tedu.pojo

创建类:Car

封装属性,设置set和get方法,重写toString()方法

package cn.tedu.pojo;
/*封装数据Model*/
public class Car {
    /*1.为什么使用引用类型(包装类型)?因为使用基本类型会抛出异常,*/
    //private int id;
    private Integer id;
    private String name;
    private String type;
    private String color;
    //private double price;
    private Double price;

    /*4.Constructor默认存在无参构造,如有含参构造,需手动添加无参构造*/
    public Car() {
    }
    /*5.全参构造,创建对象时可以直接给属性赋值*/
    public Car(Integer id, String name, String type, String color, Double price) {
        this.id = id;
        this.name = name;
        this.type = type;
        this.color = color;
        this.price = price;
    }

    /*3.toString()重写顶级父类,重写后打印的是具体内容*/
    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
    /*2.封装属性需要提供set/get方法*/
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

 4.2、改造CarController

1、方式一:无参构造创建对象设置属性

作用:把资源发送到网页上

package cn.tedu.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController//接收请求
@RequestMapping("car")//规定了浏览器的访问这个类的方式
public class CarController {

    @RequestMapping("get")//规定了浏览器访问这个方法
    public Car get(){
        //System.out.println(1000);控制台打印
        //保时捷718 Cayman T,红色,641000元起
        Car car = new Car();
        car.setId(718);
        car.setName("保时捷");
        car.setType("Cayman T");
        car.setColor("红色");
        car.setPrice(641000.0);

        return car;
    }
}

 1)网页访问地址:localhost:8080/car/get

2)网页显示结果:

{"id":718,"name":"保时捷","type":"Cayman T","color":"红色","price":641000.0}

2、方式二:全参构造创建对象直接属性赋值

package cn.tedu.controller;

import cn.tedu.pojo.Car;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("car")
public class CarController {
    @RequestMapping("get")
    public String get(){
        return "一码一高度,巅峰不远处" ;
    }
    //提供汽车相关的数据
    @RequestMapping("get2")
    public Car get2(){
         //http://localhost:8080/car/get2
        // {"id":718,"name":"保时捷","type":"Cayman T","color":"红色","price":641000.0}
        Car car=new Car(718,"保时捷","Cayman T","红色",641000.00 );
        return car ;
    }
}

在这里插入图片描述

 

4.3、前后端关联,改造网页,在html网页超链接获取数据--View

想要在HTML网页超链接绑定点开mvc数据:
1)在HTML超链接href绑定mvc固定地址格式:localhost:8080/car/get2
2)需要重启服务器tomcat
3)打开HTML网页点击指定链接名,即可跳出car类的信息(car对象)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>测试SpringMVC</title>
	</head>
	<body>
		<a href="http://localhost:8080/car/get">点我发起请求</a>
		<br>
		<a href="http://localhost:8080/car/get2">点我发起汽车类请求</a>
	</body>
</html>

三、利用SpringMVC解析请求参数

1、概述

当客户端打开浏览器要访问服务器时,可能会带着一些http请求参数过来.

这时,服务器需要获取http参数进行业务处理,如何处理http请求并获取参数呢?

总共有8种,重点时两种方式:GET方式和POST方式

2、浏览器提交请求数据的方式

get:把请求参数 在地址栏拼接http://localhost:8080/car/insert?id=1&name=张三&age=18
post:安全,数据不在地址栏展示

3、get方式解析请求参数

1)html修改网页:

2)idea修改controller: 

注意:@RequestMapping注解的方法名不能相同,底层Map(k,v),要求无序无下标不能重复,其中k就是url,即localhost:8080/car/add1,如果最后方法名相同,导致程序不知道调用哪一个,给不到我们想要的类的属性。

package cn.tedu.controller;

import cn.tedu.pojo.Car;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("car")
public class CarController {
    //1.框架解析请求参数http://localhost:8080/car/add?id=1
    @RequestMapping("add")
    public void add(int id){//把地址栏里的参数值交给局部变量id保存
        System.out.println(id);
    }
    
    //2.框架解析请求参数http://localhost:8080/car/add1?id=1&name=张三
    @RequestMapping("add1")
    public void add1(int id ,String name){//把地址栏里的参数值交给局部变量id,name保存
        System.out.println(id+name);
    }
    //3.SpringMVC解析汽车类请求多个参数
    //http://localhost:8080/car/add2?id=718&name=保时捷&type=Cayman T&color=红色&price=641000.0
    @RequestMapping("add2")
    public Car add2(Car car){//把地址栏的参数值交给car类对应局部变量保存
        System.out.println(car);//打印在控制台
        return car;//内容返回到网页
    }
}

四、SpringMVC常见问题解决

1、404-请求的url不存在

在这里插入图片描述

解决方案: java严格区分大小写,把地址改成:http://localhost:8080/car/get即可

在这里插入图片描述

 2、500--请求的url未绑定参数

在这里插入图片描述

 get3方法明显是需要参数的,那就请求时,必须传入参数,否则页面报错500,IDEA中抛出了IllegalStateException的异常。
解决方案:

可以将url改成:http://localhost:8080/car/get3?id=10 即可。给参数或者把基本类型改为引用类型
或者:把方法的参数改为引用类型,int改成Integer,即使请求时忘记传入参数,也不会抛出异常
 

3、400-url 的请求和服务器需要的参数类型不同

在这里插入图片描述

在这里插入图片描述 问题:需要int类型的参数哦却给了一个double类型的参数

解决方案:改变相应的基本类型或者参数哦

五、restful风格解析请求参数

1、项目结构

在这里插入图片描述

 2、修改网页

在这里插入图片描述

3、修改car

package cn.tedu.pojo;
//Model
public class Car {
    private Integer id ;
    private String name ;
    private String type ;
    private String color ;
    private Double price ;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                '}';
    }
}

4、修改CarController

package cn.tedu.controller;

import cn.tedu.pojo.Car;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("car")
public class CarController {
    //解析浏览器用get方式发来的汽车数据
    @RequestMapping("get")
    public Car get(){
        Car c = new Car();
        c.setId(100);
        c.setPrice(19.9);
        return c;
    }

    //普通get方式提交的数据:http://localhost:8080/car/add?id=10&name=BMW&price=9.9
    @RequestMapping("add")
    public String add(Integer id,String name,Double price){
        return id+name+price ;
    }
/**优化get提交数据的方式restful:http://localhost:8080/car/add2/10/BMW/9.9*/
    @RequestMapping("add2/{id}/{y}/{x}")//{id}是占位符,表示这个参数的位置
    public void add2(@PathVariable Integer id, //@PathVariabl用来获取{}中间的值
                     @PathVariable String y,
                     @PathVariable Double x){
        System.out.println(id+y+x);
    }

}


5、测试

在这里插入图片描述

六、ajax提交请求数据

1、创建新的网页html,添加ajax代码

注意点

1)一定要导入jQuery包

2)严格填写标点符号,单词书写正确,否则就是语法错误

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="old/jquery-1.8.3.min.js"></script>
		<script>
			function a(){
				$.ajax({
					type: "get" ,//要使用的请求方式
					url:"http://localhost:8080/car/get" , //要使用的请求路径 
					data: {//要拼接的数据---必须是JSON串
						"id":"10",
						"name":"BMW",
						"price":"9.9"
					},
					success: function(data){ //成功时得到js对象
						console.log(data);
						console.log(data.id);//使用js方法获取想要的属性
						alert(100);
					}
				})
			}
		</script>
	</head>
	<body>
		<a onclick="a();" href="#">点我获取汽车数据</a>
	</body>
</html>

2、改造CarController类,加一个跨域的注解@CrossOrigin

注意:ajax只能和get方法联用,不能和add、add2方法联用

package cn.tedu.controller;

import cn.tedu.pojo.Car;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("car")
@CrossOrigin //----解决跨域问题
public class CarController {
    //解析浏览器用get方式发来的汽车数据
    @RequestMapping("get")
    public Car get(){
        Car c = new Car();
        c.setId(100);
        c.setPrice(19.9);
        return c;
    }

    //普通get方式提交的数据:http://localhost:8080/car/add?id=10&name=BMW&price=9.9
    @RequestMapping("add")
    public String add(Integer id,String name,Double price){
        return id+name+price ;
    }
//优化get提交数据的方式restful:http://localhost:8080/car/add2/10/BMW/9.9
    @RequestMapping("add2/{id}/{y}/{x}")//{id}是占位符,表示这个参数的位置
    public void add2(@PathVariable Integer id, //@PathVariabl用来获取{}中间的值
                     @PathVariable String y,
                     @PathVariable Double x){
        System.out.println(id+y+x);
    }

}

3、测试

在这里插入图片描述

七、SpringMVC常用的注解


@Controller 标识是一个Controller,Spring包扫描创建实例

@RequestMapping 请求后的映射路径

@PathVariable 标识接收单个参数

@ResponseBody 返回对象利用jackson工具类转换为json字符串

@RequestParam 参数名和请求参数名称不同时使用,可以设置默认值
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书是国内唯一一本系统分析Spring源代码的著作,也是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔,Java开发者社区和Spring开发者社区联袂推荐。本书第1版不仅在内容上获得了读者的广泛好评,而且在销量上也摘取了同类书的桂冠,曾经一度掀起Java类图书的销售热潮。第2版不仅继承了第1版在内容组织和写作方式上的优点,而且还根据广大读者的反馈改进了若干细节上的不足。更为重要的是,结合Spring的最版本对过时的内容进行了更,并增加了大量内容,使本书更趋近于完美。本书从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的优秀架构和设计思想,还能从Spring优雅的实现源码中一窥Java语言的精髓。本书在开篇之前对Spring的设计理念和整体架构进行了全面的介绍,能让读者从宏观上厘清Spring各个功能模块之间的关系;第一部分详细分析了Spring的核心:IoC容器和AOP的实现,能帮助读者了解Spring的运行机制;第二部分深入阐述了各种基于IoC容器和AOP的JavaEE组件在Spring中的实现原理;第三部分讲述了ACEGI安全框架、DM模块以及Flex模块等基于Spring的典型应用的设计与实现。无论你是Java程序员、Spring开发者,还是平台开发人员、系统架构师,抑或是对开源软件源代码着迷的代码狂人,都能从本书中受益。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值