SpringMVC 框架基础知识

【补】2. 为什么要使用 SpringMVC 框架

在原生的 Java EE 技术体系中,处理用户请求的是Servlet组件,通常情况下,每个Servlet组件处理 1 种请求,例如“用户注册”的请求可能由UserRegServlet来处理,“用户登录”的请求可能由UserLoginServlet来处理……在比较复杂的业务系统中,用户提交的请求的种类可能特别多,就会导致Servlet组件的数量也特别多!进而导致代码的管理难度很大,同时,在项目运行时,诸多的Servlet组件也会占用较多的内存空间……

在 SpringMVC 框架的设计中,就解决了以上问题,它使用 1 个DispatcherServlet的组件,用于接收所有请求(当然,也可以配置为某些特定的请求,例如配置为仅处理*.do的请求),以此减少Servlet组件的数量!

原本Servlet是用于处理请求的,而在 SpringMVC 框架中,DispatcherServlet的主要作用是接收到请求后,分发到具体处理请求的Controller组件,其本身并不处理请求!而 SpringMVC 中的每个Controller组件都可以有若干个处理请求的方法,也就是每个Controller组件都可以处理若干种请求,所以,即使项目很复杂,请求的种类很多,但是,Controller组件的数量并不会太多!

DispatcherServletController的关系就好比银行大厅的取号机和业务柜台的关系。

SpringMVC 框架的使用比原生的 Java EE 更加简单!

1. 显示页面

在项目的 pom.xml 中添加thymeleafthymeleaf-spring5这 2 个依赖:

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring5 -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>

注意:同一个groupId下,各artifactId不同,但是,如果version的编号规则是一样的,并且,在同一个项目中需要使用不同artifactId对应的依赖,必须使用相同的version

package cn.haiyong.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

@ComponentScan("cn.haiyong.spring")
public class SpringMvcConfigurer implements WebMvcConfigurer {

  private String characterEncoding = "utf-8";
  
  @Bean
  public ViewResolver configViewResolver() {
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    templateResolver.setCharacterEncoding(characterEncoding);
    templateResolver.setTemplateMode("HTML");
    templateResolver.setCacheable(false);
    templateResolver.setPrefix("/templates/");
    templateResolver.setSuffix(".html");
    
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);
    
    ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    viewResolver.setCharacterEncoding(characterEncoding);
    viewResolver.setTemplateEngine(templateEngine);
    return viewResolver;
  }
  
}

2. 接收客户端提交的请求参数

2.1. 使用 HttpServletRequest 接收请求参数

在处理请求的方法的参数列表中,添加HttpServletRequest类型的参数,在处理过程中,调用参数对象的getParameter()方法即可获取请求参数:

@RequestMapping("handle_reg.do")
@ResponseBody
public String handleReg(HttpServletRequest request) {
    System.out.println("HelloController.handleReg()");

    String username = request.getParameter("username");
    String password = request.getParameter("password");
    Integer age = Integer.valueOf(request.getParameter("age"));
    String phone = request.getParameter("phone");
    String email = request.getParameter("email");
    System.out.println("username=" + username);
    System.out.println("password=" + password);
    System.out.println("age=" + age);
    System.out.println("phone=" + phone);
    System.out.println("email=" + email);

    return "OK."; // 暂时不关心如何响应,所以使用@ResponseBody返回某个字符串,避免程序报错
}

2.2. 将请求参数直接声明为处理请求的方法的参数

可以将客户端提交的请求参数直接声明为处理请求的方法的参数,例如:

@RequestMapping("handle_reg.do")
@ResponseBody
public String handleReg(String username, String password, Integer age, 
        String phone, String email) {
    System.out.println("HelloController.handleReg()");

    System.out.println("[2] username=" + username);
    System.out.println("[2] password=" + password);
    System.out.println("[2] age=" + age);
    System.out.println("[2] phone=" + phone);
    System.out.println("[2] email=" + email);

    return "OK."; // 暂时不关心如何响应,所以使用@ResponseBody返回某个字符串,避免程序报错
}

在声明参数时,需要保证名称的一致,即“客户端提交的请求参数的名称”与“处理请求的方法的参数名称”必须是一致的!如果服务器端声明的参数,在客户端提交请求时并没有提交,则服务器端声明的参数值将是null

在处理请求的方法中,声明参数时,可以将参数的类型声明为所期望的类型,例如以上代码中,就将age声明为Integer类型,当然,前提是客户端最终提交的数据是可以转换为Integer,如果客户端提交的数据根本就无法转换,则会报错。

使用这种虽然简单、方便,但是,不适用于请求参数过多的应用场景!

2.3. 使用封装的参数对象接收请求参数

可以将客户端将要提交的各请求参数封装到一个自定义的数据类型中,例如:

package cn.haiyong.spring;

public class User {

  private String username;
  private String password;
  private Integer age;
  private String phone;
  private String email;
    
    // Getters & Setters
    // toString()
    
}

然后,将以上自定义的数据类型添加到处理请求的方法的参数列表中即可:

@RequestMapping("handle_reg.do")
@ResponseBody
public String handleReg(User user) {
    System.out.println("HelloController.handleReg()");

    System.out.println(user);

    return "OK."; // 暂时不关心如何响应,所以使用@ResponseBody返回某个字符串,避免程序报错
}

2.4. 小结

首先,在 2.1 介绍的使用HttpServletRequest接收请求参数的做法是不推荐使用的;

如果请求参数的数量较少,并且固定时,应该优先使用 2.2 介绍的做法;

如果请求参数的数量较多,或以后存在调整的可能性时,应该优先使用 2.3 介绍的做法。

另外,以上 2.2 和 2.3 的做法可以同时存在!

3. 向模版页面转发数据

当需要向 Thymeleaf 模版页面转发数据时,应该先在处理请求的方法的参数列表中添加ModelMap类型的参数,并在需要转换数据时,调用ModelMap参数对象的addAttribute()方法将数据封装进去:

@RequestMapping("handle_login.do")
public String handleLogin(String username, String password, ModelMap modelMap) {
    System.out.println("UserController.handleLogin()");
    System.out.println("username=" + username);
    System.out.println("password=" + password);

    // 假设root/1234是正确的用户名/密码
    // 判断用户名
    if ("root".equals(username)) {
        // 用户名正确,判断密码
        if ("1234".equals(password)) {
            // 密码也正确,则登录成功
            return "OK";
        } else {
            // 密码错误
            String message = "登录失败!密码错误!";
            modelMap.addAttribute("errorMessage", message);
            return "error";
        }
    } else {
        // 用户名错误
        String message = "登录失败!用户名错误!";
        modelMap.addAttribute("errorMessage", message);
        return "error";
    }
}

后续,在 Thymeleaf 模版页面中,使用 Thymeleaf 表达式即可显示此前封装的数据:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>操作错误</title>
</head>
<body>
<h1>操作错误:<span th:text="${errorMessage}"></span></h1>
</body>
</html>

小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾听铃的声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值