前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC入门

SpringMVC入门

作者头像
Cikian.
发布2023-08-09 19:13:28
1680
发布2023-08-09 19:13:28
举报
文章被收录于专栏:Cikian技术站

一、SpringMVC简介

1. SpringMVC概述

  • SpringMVC技术与Servlet技术功能等同,均属于web层(表现层)开发技术
  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
  • 优点:
    • 使用简单,开发便捷(相比于Servlet)
    • 灵活性强

二、入门案例

使用SpringMVC需要先导入SpringMVC坐标与Servlet坐标

代码语言:javascript
复制
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.0.11</version>
</dependency>

创建SpringMVC控制器类(等同于Servlet功能)

代码语言:javascript
复制
@Controller
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save() {
        System.out.println("UserController.save()");
        return "{'info':'SpringMVC'};";
    };
};

初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean

代码语言:javascript
复制
@Configuration
@ComponentScan("com.cikian")
public class SpringMvcConfig {
};

初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求

代码语言:javascript
复制
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return null;
    };

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

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    };
};

SpringMVC入门程序开发总结(1+N)

  • 一次性工作
    • 创建工程,设置服务器,加载工程
    • 导入坐标
    • 创建web容器启动类,加载pringMVC配置,并设置SpringMVC请求拦截路径
    • SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
  • 多次工作
    • 定义处理请求的控制器类
    • 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)

三、工作流程分析

  • 启动服务器初始化过程
    1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器
    2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
    3. 加载SpringMvcConfig
    4. 执行@ComponentScan加载对应的bean
    5. 加载JserController,每个@RequestMapping的名称对应一个具体的方法
    6. 执行getServletMappings,方法,定义所有的请求都通过SpringMVC
  • 单次请求过程
    1. 发送请求localhost/save
    2. web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
    3. 解析请求路径/save
    4. 由/save匹配执行对应的方法save()
    5. 执行save()
    6. 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方

四、bean加载控制

Controller加载控制与业务bean加载控制

  • SpringMVC相关bean(表现层bean)
  • Spring控制的bean
    • 业务bean(Service)
    • 功能bean(DataSources等)

如何避免Spring加载SpringMVC加载的bean

SpringMVC相关bean加载控制

  • SpringMVC加载的bean对应的包均在com.controller包内

Spring相关bean加载控制

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

代码语言:javascript
复制
@ComponentScan(value = "com.cikian",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
        )
)

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

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

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

名称:@ComponentScan 类型:类注解 范例: @Configuration @ComponentScan(value = "com.cikian", excludeFilters = @ComponentScan.Filter( type = FilterType.ANNOTATION, classes = Controller.class ) ) public class SpringConfig { }; 属性:

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

简化ServletContainersInitConfig配置类: public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class};; }; @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class};; }; @Override protected String[] getServletMappings() { return new String[]{"/"};; }; };

五、请求

1. 请求映射路径

为了防止请求路径设置重复,可以给不同模块设置不同的请求路径前缀

名称:@RequestMapping 类型:方法注解 类注解 位置:SpringMVC控制器方法定义上方 作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀 范例: @RequestMapping("/user") @Controller public class UserController { @RequestMapping("/save") @ResponseBody public String save() { System.out.println("user/save执行。。。"); return "{'info':'usersave'};"; }; @RequestMapping("/data") @ResponseBody public String data() { System.out.println("user/data执行。。。"); return "{'msg':'userdata'};"; }; }; 属性: value(默认):请求访问路径,或访问路径前缀

2. 接收请求参数

接收请求参数:直接在方法中加上对应的形参即可:

代码语言:javascript
复制
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name,int age) {
    System.out.println("参数传递:" + name);
    System.out.println("参数传递:" + age);
    return "{'msg':'commonParam'};";
};

处理中文乱码问题 在ServletContainersInitConfig配置类中,设置过滤器,重写getServletFilters方法: @Override protected Filter[] getServletFilters() { CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF8"); return new Filter[]{characterEncodingFilter};; };

3. 参数种类

普通参数

url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数。或使用@RequestParam注解将请求参数与形参绑定,如:

代码语言:javascript
复制
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(@RequestParam("username") String name, int age) {
    System.out.println("参数传递:" + name);
    System.out.println("参数传递:" + age);
    return "{'msg':'commonParam'};";
};
POJO类型参数
代码语言:javascript
复制
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user) {
    System.out.println("参数传递:" + user);
    return "{'msg':'pojoParam'};";
};

User类中有name与age属性,参数传递过来时,会自动将对应名称的属性封装进pojo类

嵌套POJO类型参数

当pojo类型参数的实体对象中有引用的对象时,如User类中还引用Address类,此时可以下面方式传递:

127.0.0.1/user/pojoParam2/?name=张三&age=18&address.province=河北&address.city=秦皇岛

数组类型参数
代码语言:javascript
复制
@RequestMapping("/arrayParam")
@ResponseBody
public String pojoParam(String[] likes) {
    System.out.println("参数传递:" + Arrays.toString(likes));
    return "{'msg':'arrayParam'};";
};

传递数组类型参数时,在访问时,使用多个向明名称的访问参数,如:

localhost/user/arrayParam?likes=吃&likes=喝&likes=拉&likes=撒&likes=睡

集合类型参数

当接收List集合参数时,传递参数的方式与数组类型参数传递方式一样,在接收参数时,要在形参前使用@RequestParam注解,如:

代码语言:javascript
复制
@RequestMapping("/listParam")
@ResponseBody
public String pojoParam(@RequestParam List<String> likes) {
    System.out.println("参数传递:" + likes);
    return "{'msg':'listParam'};";
};
传递json数据

导入处理json数据的坐标

代码语言:javascript
复制
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

在SpringMvcConfig中使用@EnableWebMvc注解开启由json数据转换成对象的功能

代码语言:javascript
复制
@Configuration
@ComponentScan("com.cikian.controller")
@EnableWebMvc
public class SpringMvcConfig {};

在就收参数的方法的形参前加@RequestBody注解

传递json数组

代码语言:javascript
复制
@RequestMapping("/jsonParam")
@ResponseBody
public String jsonParam(@RequestBody List<String> likes) {
    System.out.println("参数传递:" + likes);
    return "{'msg':'jsonParam'};";
};

请求参数:

代码语言:javascript
复制
["game","music","code"]

传递json对象(POJO)

代码语言:javascript
复制
@RequestMapping("/jsonPojoParam")
@ResponseBody
public String jsonPojoParam(@RequestBody User user) {
    System.out.println("参数传递:" + user);
    return "{'msg':'jsonPojoParam'};";
};

请求参数:

代码语言:javascript
复制
{
    "name":"陈",
    "age":18,
    "address":{
        "province":"河北",
        "city":"秦皇岛"
    };
};

传递json对象数组(POJO)

代码语言:javascript
复制
@RequestMapping("/jsonPojoListParam")
@ResponseBody
public String jsonPojoListParam(@RequestBody List<User> users) {
    System.out.println("参数传递:" + users);
    return "{'msg':'jsonPojoListParam'};";
};

请求参数:

代码语言:javascript
复制
[
    {
        "name":"张三",
        "age":15,
        "address":{
            "province":"河北",
            "city":"秦皇岛"
        };
    };,
    {
        "name":"李四",
        "age":18,
        "address":{
            "province":"北京",
            "city":"北京"
        };
    };
]

  • 名称:@RequestBody
  • 类型:形参注解
  • 位置:SpringMVC控制器方法形参定义前面
  • 作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

@RequestBody@RequestParam

  • 区别:
    • @RequestParam用于接收url地址传参,表单传参【application/X-www-form-urlencoded】
    • @RequestBody用于接收json数据【application/json】
  • 应用:
    • 后期开发中,发送json格式数据为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
日期类型参数传递

日期类型数据基于系统不同格式也不尽相同,如:

  • 2023-08-07
  • 2023/08/07
  • 07/08/2023

默认接收"yyyy/MM/dd HH:mm:ss"格式日期,可以使用@DateTimeFormat注解自定义传入格式:

代码语言:javascript
复制
@RequestMapping("/dateParam")
@ResponseBody
public String dateParam(Date date1,
                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date date2,
                        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date3) {
    System.out.println("参数传递:" + date1);
    System.out.println("参数传递:" + date2);
    System.out.println("参数传递:" + date3);
    return "{'msg':'dateParam'};";
};

如此定义,请求参数:

localhost/user/dateParam?date1=2023/08/07 20:30:50&date2=2023-08-07&date3=2023-08-07 15:25:30中的三种日期都能正确接收

  • 名称:@DateTimeFormat
  • 类型:形参注解
  • 位置:SpringMVC控制器方法形参前面
  • 作用:设定日期时间型数据格式
  • 属性:parattern:日期时间格式字符串

Converter接口 public interface Converter<S, T> { @Nullable T convert(S var1); };

  • 请求参数年龄数据(String→Integer)
  • 日期格式转换(String→Date)
  • ……

@EnableWebMvc功能之一:根据类型匹配对应的类型转换器

六、响应

1. 响应页面

代码语言:javascript
复制
@RequestMapping("/toJumpPage")
public String toJumpPage() {
    System.out.println("跳转页面。。。");
    return "/page.jsp";
};

在方法中返回的字符串默认会被当做响应的页面文件的名称

2. 响应数据

响应文本数据:

代码语言:javascript
复制
@RequestMapping("/toText")
@ResponseBody
public String toText() {
    System.out.println("返回纯文本");
    return "response text";
};

响应json数据(对象转json):

代码语言:javascript
复制
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO() {
    System.out.println("返回json对象");
    User user = new User();
    user.setName("陈cikian");
    user.setAge(18);
    return user;
};

响应json数组(对象集合转json数组):

代码语言:javascript
复制
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList() {
    User user1 = new User();
    user1.setName("张三");
    user1.setAge(15);

    User user2 = new User();
    user2.setName("李四");
    user2.setAge(120);
    List<User> users = Arrays.asList(user1, user2);
    return users;
};

  • 名称:@ResponseBody
  • 类型:方法注解
  • 位置:SpringMVC控制器方法定义上方
  • 作用:设置当前控制器方法响应内容为当前返回值,无需解析

类型转换的功能来自HttpMessageConverter接口

七、REST风格

1. 简介

2. RESTful入门案例

代码语言:javascript
复制
@Controller
public class UserController {
    @RequestMapping(value = "/users", method = RequestMethod.POST)
    @ResponseBody
    public String save(User user) {
        System.out.println("user.save:" + user);
        return "{'info':'user.save'};";
    };

    @RequestMapping(value = "/users/{id};", method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id) {
        System.out.println("user.delete:" + id);
        return "{'info':'user.delete'};";
    };

    @RequestMapping(value = "/users", method = RequestMethod.PUT)
    @ResponseBody
    public String update(@RequestBody User user) {
        System.out.println("user.update:" + user);
        return "{'info':'user.update'};";
    };

    @RequestMapping(value = "/users/{id};", method = RequestMethod.GET)
    @ResponseBody
    public String getById(@PathVariable Integer id) {
        System.out.println("user.getById:" + id);
        return "{'info':'user.getById'};";
    };

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    @ResponseBody
    public String getAll() {
        System.out.println("user.getAll:");
        return "{'info':'user.getAll'};";
    };
};
  1. 设定http请求动作,如:method = RequestMethod.POST
  2. 设定请求参数(路径变量) 请求路径中要有对应参数的占位,如:/users/{id},形参前使用@PathVariable注解,如:@PathVariable Integer id,占位符的名称应与形参名称相同。

  • 名称:@RequestMapping
  • 类型:方法注解
  • 位置:SpringMVC控制器方法定义上方
  • 作用:设置当前控制器方法请求访问路径
  • 属性:
    • value(默认):请求访问路径
    • method:http请求动作,标准动作(GET/POST/PUT/DELETE)

  • 名称:@PathVariable
  • 类型:形参注解
  • 位置:SpringMVC控制器方法形参定义前面
  • 作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应

@RequestBody @RequestParam @PathVariable

  • 区别
    • @RequestParam用于接收url地址传参或表单传参
    • @RequestBody用于接收请求体数据,主要为json数据
    • @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • 应用
    • 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
    • 采用RESTfuli进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值

3. REST快速开发

上述案例代码可修改为以下内容:

代码语言:javascript
复制
@RestController
@RequestMapping("/users")
public class UserController {
    @PostMapping
    public String save(@RequestBody User user) {
        System.out.println("user.save:" + user);
        return "{'info':'user.save'};";
    };

    @DeleteMapping("/{id};")
    public String delete(@PathVariable Integer id) {
        System.out.println("user.delete:" + id);
        return "{'info':'user.delete'};";
    };

    @PutMapping
    public String update(@RequestBody User user) {
        System.out.println("user.update:" + user);
        return "{'info':'user.update'};";
    };

    @GetMapping("/{id};")
    public String getById(@PathVariable Integer id) {
        System.out.println("user.getById:" + id);
        return "{'info':'user.getById'};";
    };

    @GetMapping
    public String getAll() {
        System.out.println("user.getAll:");
        return "{'info':'user.getAll'};";
    };
};

  • 名称:@RestController
  • 类型:类注解
  • 位置:基于SpringMVC的RESTful开发控制器类定义上方
  • 作用:设置当前控制器类为RESTful,风格,等同于@Controller@ResponseBody两个注解组合功能

  • 名称:@GetMapping @PostMapping @PutMapping @DeleteMapping
  • 类型:方法注解
  • 位置:基于SpringMVC的RESTful开发控制器方法定义上方
  • 作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,如:@GetMapping对应GET请求
  • 属性:value(默认):请求访问路径

八、补充:对静态资源放行

由于设置了SpringMVC拦截所有路径请求,所以会导致访问不到静态资源,如html文件、css文件、js文件、图片等,所以需要设置放行拦截路径,在config包下创建SpringMvcSupport配置类,内容如下:

代码语言:javascript
复制
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("classpath:/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("classpath:/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/");
        registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img/");
    };
};

然后在SpringMVC配置类中将此配置类导入,导入方法不唯一,例如:@ComponentScan({"com.cikian.controller", "com.cikian.config"})

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、SpringMVC简介
    • 1. SpringMVC概述
    • 二、入门案例
    • 三、工作流程分析
    • 四、bean加载控制
    • 五、请求
      • 1. 请求映射路径
        • 2. 接收请求参数
          • 3. 参数种类
            • 普通参数
            • POJO类型参数
            • 嵌套POJO类型参数
            • 数组类型参数
            • 集合类型参数
            • 传递json数据
            • 日期类型参数传递
        • 六、响应
          • 1. 响应页面
            • 2. 响应数据
            • 七、REST风格
              • 1. 简介
                • 2. RESTful入门案例
                  • 3. REST快速开发
                  • 八、补充:对静态资源放行
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档