学习日记(SpringMVC_part_one)

目录

SpringMVC框架

关于postman的使用介绍

SpringMVC入门案例

1、添加依赖(spring-webmvc和javax.servlet-api)

2、设置配置类文件SpringMVCConfig

3、定义表现层控制器UserController并且定义为bean

[4、配置web容器配置类(方式一 || 方式二)](#4、配置web容器配置类(方式一 || 方式二))

5、使用postman发送请求

小结

代码的执行流程分析

代码阶段

测试阶段

Spring的bean与SpringMVC的bean区别

如何将他们分开定义,放在不同的容器里面(SpringConfig和SpringMVCConfig)

REST风格

目的隐藏具体的操作行为

REST的简化方式三种

[一个案例 (books) 存在的问题 ???](#一个案例 (books) 存在的问题 ???)


SpringMVC框架

Spring MVC 是一种基于 Java 的 Web 应用程序框架,它是 Spring 框架的一部分,用于简化开发基于 Web 的应用程序。Spring MVC 就像是一个网站的建筑队长,它帮助开发者把网站的不同部分组织起来,让整个网站看起来更有条理。它把网站分成了三个部分:一个负责管理数据的部分(模型),一个负责展示页面的部分(视图),还有一个负责控制页面流程的部分(控制器)。

关于postman的使用介绍

新手如何使用postman(新手使用,简单明了)_postman使用教程-CSDN博客

SpringMVC入门案例

(SpringMVCConfig -> ServletContainersInitConfig > UserController)

1、添加依赖(spring-webmvc和javax.servlet-api)

2、设置配置类文件SpringMVCConfig

java 复制代码
package com.example.Config;

import org.springframework.context.annotation.Configuration;

//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan({"com.example.Controller"})
@EnableWebMvc
public class SpringMvcConfig {
}

3、定义表现层控制器UserController并且定义为bean

java 复制代码
package com.example.Controller;

import com.example.model.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.xml.crypto.Data;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Controller
public class UserController {

    @RequestMapping("/save")
    @ResponseBody
    public String save() {
        System.out.println("User Controller save...");
        return "{'info':spring-MVC}";
    }

    @RequestMapping("/commonParam")
    @ResponseBody
    public String commonParam(String name, int age) {
        System.out.println("普通参数传递:" + name + "," + age);
        return "{'Param':name & age}";
    }

    @RequestMapping("/commonParamDifferentName")
    @ResponseBody
    public String commonParamDifferentName(@RequestParam("name") String userName, @RequestParam("age") int MyAge) {
        System.out.println("普通参数传递:" + userName + "," + MyAge);
        return "{'DifferentNameParam':name & age}";
    }

    @RequestMapping("/PojoParam")
    @ResponseBody
    public String PojoParam(User user) {
        System.out.println("Pojo参数传递:" + user);
        return "{'User-PojoParam':name & age}";
    }

    @RequestMapping("/ContainPojoParam")
    @ResponseBody
    public String ContainPojoParam(User user) {
        System.out.println("嵌套的Pojo参数传递:" + user);
        return "{'User & address-PojoParam':user & age & province & city}";
    }

    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] arrayName) {
        System.out.println("数组参数传递:" + Arrays.toString(arrayName));
        return "{'Array-Param':array}";
    }

    @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> listName) {
        System.out.println("集合参数传递:" + listName);
        return "{'List-Param':List}";
    }

    @RequestMapping("/listParamForJson")
    @ResponseBody
    public String listParamForJson(@RequestBody List<String> likes) {
        System.out.println("列表类型使用josn参数传递:" + likes);
        return "{list common for json param}";
    }

    @RequestMapping("/pojoParamForJson")
    @ResponseBody
    public String pojoParamForJson(@RequestBody User user) {
        System.out.println("列表类型使用josn参数传递:" + user);
        return "{pojo for json param}";
    }

    @RequestMapping("/listPojoParamForJson")
    @ResponseBody
    public String listPojoParamForJson(@RequestBody List<User> user) {
        System.out.println("列表类型使用josn参数传递:" + user);
        return "{list pojo for json param}";
    }

    @RequestMapping("/dataParam")
    @ResponseBody
    public String dataParam(Date date, @DateTimeFormat(pattern = "yyyy-MM-dd") Date date1, @DateTimeFormat(pattern = "yyyy/MM/dd HH:mm:ss") Date date2) {
        System.out.println("日期类型的参数传递:" + date);
        System.out.println("日期类型的参数形式一传递:" + date1);
        System.out.println("日期类型的参数形式二传递:" + date2);
        return "{Data Param}";
    }

    @RequestMapping("/toJumpPage")
    public String toJumpPage() {
        System.out.println("跳转页面");
        return "page.jsp";
    }

    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("jiawwwww");
        user.setAge(25);
        return user;
    }

    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        System.out.println("返回json集合数据");
        User user1 = new User();
        user1.setName("jia00000");
        user1.setAge(28);

        User user2 = new User();
        user2.setName("jia555555");
        user2.setAge(12);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);

        return userList;
    }
}

4、配置web容器配置类(方式一 || 方式二)

java 复制代码
package com.example.Config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    原始格式,继承自AbstractDispatcherServletInitializer
    //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
    protected WebApplicationContext createServletApplicationContext() {
        //初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        //加载指定配置类
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring配置类
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

}
java 复制代码
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

//    简化格式,继承自AbstractAnnotationConfigDispatcherServletInitializer
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
}

5、使用postman发送请求

6、小结

在上面的案例中,我们只需要多次完成UserController的文件编写,其他都是只需要一次编写的一劳永逸的

请求参数(get & post)

UserController.commonParam(String name,int age){} ==> 要求参数名必须要一致

UserController.commonParamDifferentName(@RequestParam("name") String userName, @RequestParam("age") int MyAge)

UserController.PojoParam(User user)

UserController.ContainPojoParam(User user) ==>嵌套的使用model

UserController.arrayParam(String[] arrayName)

UserController.listParam(@RequestParam List<String> listName)

开启josn(需要添加依赖)数据的支持:在SpringMVCConfig里面添加@EnableWebMVC,在上面的方法中加入@RequestBody

  • json普通数组(["","","",...])

  • json对象({key:value,key:value,...})

  • json对象数组([{key:value,...},{key:value,...}])

UserController.listParamForJson(@RequestBody List<String> likes)

UserController.pojoParamForJson(@RequestBody User user)

UserController.listPojoParamForJson(@RequestBody List<User> user)

注意在使用时需要调整postman传递参数的形式(1、选择body 2、text改成josn)

日期类型的导入 @DateTimeFormat

UserController.dataParam(Date date, @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2)

如何响应josn页面:返回字符型的 return "page.jsp"; 前提是page.jsp必须存在

UserController.toJumpPage()

如何响应文本文档:返回字符型的文本即可 前面的案例均会返回文本文档

如何响应josn数据:返回具体类型的对象,return user

UserController.toJsonPOJO()

如何响应josn数据集合:返回列表类型的对象

UserController.toJsonList()

代码的执行流程分析

1、代码阶段

  1. 服务器启动,执行 ServletContainersInitConfig 类,初始化 web 容器

  2. 执行 createServletApplicationContext 方法,创建了 WebApplicationContext 对象

  3. 加载 SpringMvcConfig 配置类

  4. 执行@ComponentScan 加载对应的 bean

  5. 加载 UserController,每个@RequestMapping 的名称对应一个具体的方法

  6. 执行 getServletMappings 方法,定义所有的请求都通过 SpringMVC

2、测试阶段

  1. 发送请求 localhost/save

  2. web 容器发现所有请求都经过 SpringMVC,将请求交给 SpringMVC 处理

  3. 解析请求路径/save

  4. 由/save 匹配执行对应的方法 save()

  5. 执行 save()

  6. 检测到有@ResponseBody 直接将 save()方法的返回值作为响应求体返回给请求方

Spring的bean与SpringMVC的bean区别

Spring的bean:各种各样的组件,比如服务、数据库访问对象等,它们负责应用程序中的不同功能

SpringMVC的bean:这些 bean 更多地是与 Web 请求处理相关的,比如控制器(负责处理用户请求)、视图解析器(负责把数据展示给用户)、拦截器(用来处理请求之前或之后的逻辑)等等

如何将他们分开定义,放在不同的容器里面(SpringConfig和SpringMVCConfig)

  1. 方式一:Spring 加载的 bean 设定扫描范围为 com.itheima,排除掉 controller 包内的 bean

  2. excludeFilters:排除扫描路径中加载的 bean,需要指定类别(type)与具体项(classes)

  3. includeFilters:加载指定的 bean,需要指定类别(type)与具体项(classes)

例如在SpringConfig里面

@ComponentScan(value = "com.example",

excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)

)

  1. 方式二:Spring 加载的 bean 设定扫描范围为精准范围,例如 service 包、dao 包等

例如在SpringConfig里面

@ComponentScan({"com.example.dao","com.example.service"})

  1. 方式三:不区分 Spring 与 SpringMVC 的环境,加载到同一个环境中

REST风格

1、目的隐藏具体的操作行为

例如将http://localhost/user/getById?id=1 隐藏具体的操作行为变成 http://localhost/user/1

入门案例(停用UserController,使用UserController2,其他不需要改动)

2、REST的简化方式三种

解决代码中重复性较高的集中设定(RequestMappering的路径重复,method里面重复的动作)

1、在Controller类上使用@RequestMapping定义共同的访问路径。也就是在类命上方定义该类的上一级名称(在类里面的RequestMapping可以不写value)

2、使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替@RequestMapping(method=RequestMethod.XXX)

3、在Controller类上使用@RestController注解,等同于@Controller与@ResponseBody两个注解组合功能

一个案例 (books) 存在的问题 ???

1、(Book --> ServletContainerInitConfig --> SpringMvcConfig --> BookController --> SpringMvcSupport)

java 复制代码
package com.itheima.domain;

public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;

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

    public Integer getId() {
        return id;
    }

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

    public String getType() {
        return type;
    }

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

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
java 复制代码
package com.itheima.config;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}
java 复制代码
package com.itheima.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;

@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
java 复制代码
package com.itheima.controller;

import com.itheima.domain.Book;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/books")
public class BookController {

    @PostMapping
    public String save(@RequestBody Book book){
        System.out.println("book save ==> "+ book);
        return "{'module':'book save success'}";
    }

    @GetMapping
    public List<Book> getAll(){
        System.out.println("book getAll is running ...");
        List<Book> bookList = new ArrayList<Book>();

        Book book1 = new Book();
        book1.setType("计算机");
        book1.setName("SpringMVC入门教程");
        book1.setDescription("小试牛刀");
        bookList.add(book1);

        Book book2 = new Book();
        book2.setType("计算机");
        book2.setName("SpringMVC实战教程");
        book2.setDescription("一代宗师");
        bookList.add(book2);

        Book book3 = new Book();
        book3.setType("计算机丛书");
        book3.setName("SpringMVC实战教程进阶");
        book3.setDescription("一代宗师呕心创作");
        bookList.add(book3);

        return bookList;
    }

}
java 复制代码
package com.itheima.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    //设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问/pages/????时候,从/pages目录下查找内容
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

2、案例的html页面

3、josn格式输出

4、问题出现在html页面没能显示出josn的数据,在网络上尝试了很多办法依旧没有解决,所以留在后面再说吧 !!!或者谁知道的话可以讨论一下

相关推荐
西岸行者9 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意9 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码9 天前
嵌入式学习路线
学习
毛小茛9 天前
计算机系统概论——校验码
学习
babe小鑫9 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms9 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下9 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。9 天前
2026.2.25监控学习
学习
im_AMBER9 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J9 天前
从“Hello World“ 开始 C++
c语言·c++·学习