SpringMVC之综合案例

news2025/1/13 13:14:57

SpringMVC注解

  1. @Controller: 标记一个类为控制器(处理请求的类),将其作为Spring MVC的组件进行管理。

  2. @RequestMapping: 将请求URL映射到具体的处理方法上。可以用在类级别和方法级别,用于指定URL路径。

  3. @RequestParam: 用于将请求参数绑定到方法的参数上。可以指定参数名和是否必须。

  4. @PathVariable: 用于将URL中的占位符参数绑定到方法的参数上。

  5. @ResponseBody: 将方法的返回值直接写入HTTP响应体中,而不是通过视图解析器进行渲染。

  6. @RequestBody: 将HTTP请求体中的内容绑定到方法的参数上。

  7. @ModelAttribute: 用于将请求参数绑定到模型对象上。

  8. @SessionAttribute: 用于将模型对象存储到会话中,在多个请求之间共享数据。

  9. @Valid: 用于验证模型对象的有效性,配合JSR-303/349标准的注解使用。

  10. @InitBinder: 用于配置WebDataBinder,用于自定义数据绑定和格式化。

参数传递

String类型

基础类型 String 是一种表示文本的数据类型。在许多编程语言中,String 是用来存储和操作文本数据的常见类型。它可以包含任意字符,例如字母、数字、符号等。String 类型通常用于处理用户输入、存储文件内容、构建消息等场景。

在大多数编程语言中,String 类型是不可变的,这意味着一旦创建了一个字符串,就不能直接修改它的内容。相反,对于字符串的修改通常会返回一个新的字符串。这种不可变性使得字符串更安全,可以避免一些潜在的错误。

开发人员可以使用一系列的方法来操作字符串,例如连接(concatenation)、截取子串、查找和替换特定的字符等。此外,还可以比较字符串、转换大小写、格式化等。

@RequestMapping("/hello1")
    public String toHello1(Integer bid,String bname){
        log.info(">>>> 基础类型+String传参:{},{}",bid,bname);
        return "index";
    }

String 类型是一种常见的基础数据类型,用于处理文本数据并提供了许多相关的方法和操作。

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
   <html>
         <head>
    <title>Title</title>
</head>
       <body>
    <h1>springmvc 雷猴</h1>
     </body>
</html>

 paramController

package com.zhnaghao.web;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
/**
 * @author zhnaghao
 * @site 
 * @company s集团
 * @create 2023-09-06-21:44
 */
@Slf4j
@Controller
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/hello1")
    public String index(String bname,Integer bid){
//  System.out.println("真的要开始了");
    log.info("简单类型参数:bname:{},bid:{}",bname,bid);
    return "index";
    }
}

 

 复杂类型 

@RequestMapping("/hello2")
    public String toHello2(Book book,
                           HttpServletRequest req,
                           HttpServletResponse resp,
                           HttpSession session){
        System.out.println(book);
        log.info(">>>> HttpServletRequest/HttpServletResponse/HttpSession等等传参:{}", req.getRequestURI());
        return "index";
    } 

paramController类中添加 

@RequestMapping("/hello2")
    public String hello2(Book book, HttpServletRequest request){
//        System.out.println("来了");
        //servlet参数获取方式
        log.info("复杂类型参数:bname:{},bid:{}",
                request.getParameter("bname"),
                request.getParameter("bid"));
        //复杂传参
        log.info("复杂类型参数:book:{}",
                book.toString());
//      fail..error warning info debug
        return "index";
    }

 

@RequestParam 

@RequestMapping("/hello4/{bid}")
    public String toHello4(@PathVariable("bid") Integer bid){
        log.info(">>>> 使用@PathVariable注解传递参数:{}", bid);
        return "index";
    }

paramController

@RequestMapping("/hello3")
    public String toHello3(@RequestParam Integer bid,
                           @RequestParam(required = false,value = "price") Integer bookPrice,
                           @RequestParam("bookName") String bname){
        log.info(">>>> 使用@RequestParam注解传递参数:{},{},{}", bid,bname,bookPrice);
        return "index";
    }

@RequestBody

<jackson.version>2.9.3</jackson.version>
 
 <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson.version}</version>
    </dependency>

 RequestHeader 

获取请求头中的信息。

@RequestMapping("/hello7")
    public String toHello7(Book book, @RequestBody Map map, @RequestHeader("jwt") String jwt){
        System.out.println(map);
        System.out.println(book);
        System.out.println(jwt);
        return "index";
    }
 @RequestMapping("/hello7")
    public String hello7(@RequestHeader("jwt") String jwt){
//        System.out.println("宝宝");
        log.info("@RequestHeader参数:jwt:{}",jwt);
//      fail..error warning info debug
        return "index";
    }
 
    @RequestMapping("/hello8")
    public String hello8(Book book,
            @RequestBody Map map,
            @RequestHeader("jwt") String jwt){
//        System.out.println("宝宝");
        log.info("Book:Book:{}",book.toString());
        log.info("@RequestBody参数:Map:{}",map);
        log.info("@RequestHeader参数:jwt:{}",jwt);
//      fail..error warning info debug
        return "index";
    }

常用请求方法 

RequestMapping与GetMapping、PostMapping、PutMapping、DeleteMapping

他们之间的关系为:

RequestMapping=GetMapping+PostMapping+PutMapping+DeleteMapping

为什么企业中不用RequestMapping请求方法而用其他四种?

RequestMapping与GetMapping、PostMapping、PutMapping、DeleteMapping的区别:RequestMapping不安全,且不具备标识意义。

方法

//查询的请求
    @GetMapping
    public String type1(){
        System.out.println("@GetMapping:对应查询请求");
        return "index";
    }
 
    //新增的请求
    @PostMapping
    public String type2(){
        System.out.println("@PostMapping:对应新增请求");
        return "index";
    }
 
    //修改的请求
    @PutMapping
    public String type3(){
        System.out.println("@PutMapping:对应修改请求");
        return "index";
    }
 
    //删除的请求
    @DeleteMapping
    public String type4(){
        System.out.println("@DeleteMapping:对应删除请求");
        return "index";
    }
 
    //RequestMapping=GetMapping+PostMapping+PutMapping+DeleteMapping
    //RequestMapping不安全,且不具备标识意义

 返回值

创建ResponseUtil工具类辅助完成测试

package com.zhanghao.utils;
 
import com.fasterxml.jackson.databind.ObjectMapper;
 
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
 
public class ResponseUtil {
 
	public static void write(HttpServletResponse response,Object o)throws Exception{
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println(o.toString());
		out.flush();
		out.close();
	}
	
	public static void writeJson(HttpServletResponse response,Object o)throws Exception{
		ObjectMapper om = new ObjectMapper();
//		om.writeValueAsString(o)代表了json串
		write(response, om.writeValueAsString(o));
	}
}

 创建ReturnController类,测试

package com.zhanghao.web;
 
import com.zhanghao.utils.ResponseUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
 
/**
 * @author zhanghao
 * @site 
 * @company s集团
 * @create 2023-09-06-21:44
 */
@Controller
@RequestMapping("/rs")
public class ReturnController {
 
    @RequestMapping("/test01")
    public void Test01(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("午夜","塞尔维亚的舞者");
        map.put("舞者","增加成功!!!");
        ResponseUtil.writeJson(response,map);
    }
 
    @ResponseBody
    @RequestMapping("/test02")
    public Map Test02(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put(" "," ");
        map.put("1","增加成功!!!");
        return map;
    }
 
    @RequestMapping("/test03")
    public String Test03() {
        return "index02";
    }
 
    @RequestMapping("/test04")
    public String Test04(
            Model model,
            HttpServletRequest request) {
        model.addAttribute("No1","");
        request.setAttribute("No2","");
        return "index02";
    }
 
    @RequestMapping("/test05")
    public ModelAndView Test05() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("No1","");
        modelAndView.addObject("No2","");
        modelAndView.setViewName("index02");
        return modelAndView;
    }
 
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>123321</h1>
上句:  ${No1}<br>
下句:  ${No2}
</body>
</html>

 void:处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void。

 

页面跳转

创造一个PathConterller

package com.zhanghao.web;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
 
/**
 * @author zhanghao
 * @site
 * @company s集团
 * @create 2023-09-06-21:19
 */@Controller
@RequestMapping("/ts")
public class PathConterller {
 
    @ResponseBody
    @RequestMapping("/test02")
    public Map Test02(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("。");
        map.put("。","增加成功!!!");
        return map;
    }
 
    //返回值中有转发(forward)和重定向(redirect)这两种跳转方式将会绕开视图解析器的前缀和后缀
 
    //转发到(当前类)的某一个方法
    @RequestMapping("/Demo01")
    public String Demo01(){
        System.out.println("请求地址:Demo01");
        System.out.println("转发到(当前类)的某一个方法");
        return "forward:test02";
    }
 
    //转发到(其他类)的某一个方法
    @RequestMapping("/Demo02")
    public String Demo02(){
        System.out.println("请求地址:Demo02");
        System.out.println("转发到(其他类)的某一个方法");
        return "forward:/rs/test04";
    }
 
    //重定向到(其他类)的某一个方法
    @RequestMapping("/Demo03")
    public String Demo03(){
        System.out.println("请求地址:Demo03");
        System.out.println("重定向到(其他类)的某一个方法");
        return "redirect:test02";
    }
 
    //重定向到(其他类)的某一个方法
    @RequestMapping("/Demo04")
    public String Demo04(){
        System.out.println("请求地址:Demo04");
        System.out.println("重定向到(其他类)的某一个方法");
        return "redirect:/rs/test04";
    }
 
 
}

 它相当于“request.getRequestDispatcher("url").forward(request,response)”。使用转发,既可以转发到jsp, 也可以转发到其他的控制器方法。

总结

优点:

  1. 轻量级:SpringMVC相对于其他框架来说比较轻量级,不需要依赖很多的第三方库和组件。
  2. 灵活性:SpringMVC采用了灵活、可配置的设计,能够根据项目需求进行定制化配置。
  3. 松耦合:SpringMVC通过使用控制反转(IoC)和依赖注入(DI)等技术,实现了组件之间的松耦合,提高了代码的可维护性和可测试性。
  4. 易于集成:SpringMVC与Spring框架无缝集成,可以很方便地与其他Spring生态系统中的组件进行集成。
  5. 兼容性:SpringMVC支持各种视图技术,如JSP、Freemarker、Velocity等,并且支持RESTful风格的开发。

缺点:

  1. 学习曲线较陡:对于初学者来说,由于SpringMVC涉及到很多概念和技术,学习曲线较陡,需要一定的时间和精力去理解和掌握。
  2. 配置复杂:由于其灵活性和可配置性,SpringMVC的配置相对复杂,需要熟悉框架的各种配置选项和规则。
  3. 部分功能不完善:相比于其他一些框架,SpringMVC在某些功能方面可能存在一些不完善或者缺失,需要额外的开发工作来实现。
  4. 性能较低:相对于一些性能优化较好的框架来说,SpringMVC的性能可能相对较低,需要进行一定的优化和调整。

以上是SpringMVC的优点和缺点,根据具体项目需求和开发团队的技术栈选择合适的框架是很重要的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

流式数据处理与高吞吐消息传递:深入探索Kafka技术的奥秘

Kafka 是一种高吞吐量、分布式、基于发布/订阅的消息系统&#xff0c;最初由 LinkedIn 公司开发&#xff0c;使用Scala 语言编写&#xff0c;目前是 Apache 的开源项目。 Kafka 概念 Zookeeper 集群是一个基于主从复制的高可用集群&#xff0c;每个服务器承担如下三种角色中的…

【网络编程】C++实现网络通信服务器程序||计算机网络课设||Linux系统编程||TCP协议(附源码)

TCP网络服务器 &#x1f40d; 1.程序简洁&#x1f98e;2. 服务端ServerTcp程序介绍&#x1f996;3.线程池ThreadPool介绍&#x1f995; 4.任务类Task介绍&#x1f419;5. 客户端Client介绍&#x1f991;6.运行结果&#xff1a;&#x1f990; 7. 源码&#x1f99e;7.1 serverTcp…

C++内存管理(3)——内存池

1. 默认内存管理函数的不足&#xff08;为什么使用内存池&#xff09; 利用默认的内存管理操作符 new/delete 和函数 malloc()/free() 在堆上分配和释放内存会有一些额外的开销。 系统在接收到分配一定大小内存的请求时&#xff0c;首先查找内部维护的内存空闲块表&#xff0…

纯css制作常见的图形

1.正方形 <div class"square"></div> .square {width: 100px;height: 100px;background-color: #ffff00;} 效果&#xff1a; 2.长方形 <div class"rectangle"></div> .rectangle{width: 200px;height: 100px;background-color:…

用huggingface.Accelerate进行分布式训练

诸神缄默不语-个人CSDN博文目录 本文属于huggingface.transformers全部文档学习笔记博文的一部分。 全文链接&#xff1a;huggingface transformers包 文档学习笔记&#xff08;持续更新ing…&#xff09; 本部分网址&#xff1a;https://huggingface.co/docs/transformers/m…

Layui快速入门之第一节Layui的基本使用

目录 一&#xff1a;Layui的基本概念 二&#xff1a;Layui使用的基本步骤 1.在官网下载layui的基本文件&#xff0c;引入css和js文件 ①&#xff1a;普通方式引入 ②&#xff1a;第三方 CDN 方式引入 2.在script标签体中编写代码 3.测试 一&#xff1a;Layui的基本概念 …

Mac m1 安装rabbitmq+php-amqplib

rabbitmq 官方地址 https://www.rabbitmq.com mac 软件包 Downloading and Installing RabbitMQ — RabbitMQ 一.这里我选择 homebrew brew updatebrew install rabbitmq二.php代码 用composer 安装 10年软件开发经验,结交朋友! 分销商城系统开发,App商城开发 商务合作 s…

eclipse进入断点之后,一直卡死,线程一直在运行【记录一种情况】

问题描述: 一直卡死在某个断点处&#xff0c;取消断点也是卡死在这边的进程处。 解决方式&#xff1a; 将JDK的使用内存进行了修改 ① 打开eclipse&#xff0c;window->preference->Java->Installed JREs&#xff0c;选中使用的jdk然后点击右侧的edit&#xff0c;在…

打造基于终端命令行的IDE,Termux配置Vim C++开发环境

Termux配置Vim C开发环境&#xff0c;打造基于终端命令行的IDE 主要利用VimCoc插件&#xff0c;配置C的代码提示等功能。 Termux换源 打开termux&#xff0c;输入termux-change-repo 找到mirrors.tuna.tsinghua.edu.cn&#xff0c;清华源&#xff0c;空格选中&#xff0c;回…

LeetCode(力扣)40. 组合总和 IIPython

LeetCode40. 组合总和 II 题目链接代码 题目链接 https://leetcode.cn/problems/combination-sum-ii/ 代码 class Solution:def backtrackingz(self, candidates, target, result, total, path, startindex):if target total:result.append(path[:])return for i in range…

elasticsearch访问9200端口 提示需要登陆

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; elasticsearch访问9200端口 提示需要登陆 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 在E:\elasticsearch-8.9.1-windows-x86_64\elasticsearch-8.9.1\bin目录下输入命令 ela…

手写Spring:第5章-注入属性和依赖对象

文章目录 一、目标&#xff1a;注入属性和依赖对象二、设计&#xff1a;注入属性和依赖对象三、实现&#xff1a;注入属性和依赖对象3.0 引入依赖3.1 工程结构3.2 注入属性和依赖对象类图3.3 定义属性值和属性集合3.3.1 定义属性值3.3.2 定义属性集合 3.4 Bean定义补全3.5 Bean…

Flutter实用工具Indexer列表索引和Search搜索帮助。

1.列表索引 效果图&#xff1a; indexer.dart import package:json_annotation/json_annotation.dart;abstract class Indexer {///用于排序的字母JsonKey(includeFromJson: false, includeToJson: false)String? sortLetter;///用于排序的拼音JsonKey(includeFromJson: fal…

学习笔记|计数器|Keil软件中 0xFD问题|I/O口配置|STC32G单片机视频开发教程(冲哥)|第十二集:计数器的作用和意义

文章目录 1.计数器的用途2.计数器的配置官方例程开始Tips&#xff1a;编译时提示错误FILE DOES NOT EXIST&#xff1a; 3.计数器的应用本例完整代码&#xff1a;总结课后练习&#xff1a; 1.计数器的用途 直流有刷的电机,后面两个一正一负的电接上,电机就可以转 到底是转子个…

NLP(六十八)使用Optimum进行模型量化

本文将会介绍如何使用HuggingFace的Optimum&#xff0c;来对微调后的BERT模型进行量化&#xff08;Quantization&#xff09;。   在文章NLP&#xff08;六十七&#xff09;BERT模型训练后动态量化&#xff08;PTDQ&#xff09;中&#xff0c;我们使用PyTorch自带的PTDQ&…

李宏毅-机器学习hw4-self-attention结构-辨别600个speaker的身份

一、慢慢分析学习pytorch中的各个模块的参数含义、使用方法、功能&#xff1a; 1.encoder编码器中的nhead参数&#xff1a; self.encoder_layer nn.TransformerEncoderLayer( d_modeld_model, dim_feedforward256, nhead2) 所以说&#xff0c;这个nhead的意思&#xff0c;就…

使用Maven创建父子工程

&#x1f4da;目录 创建父工程创建子模块创建子模块示例创建认证模块(auth) 结束 创建父工程 选择空项目&#xff1a; 设置&#xff1a;项目名称&#xff0c;组件名称&#xff0c;版本号等 创建完成后的工程 因为我们需要设置这个工程为父工程所以不需要src下的所有文件 在pom…

WPF Flyout风格动画消息弹出消息提示框

WPF Flyout风格动画消息弹出消息提示框 效果如图&#xff1a; XAML: <Window x:Class"你的名称控件.FlyoutNotication"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xam…

java八股文面试[数据库]——索引覆盖

覆盖索引是一种避免回表查询的优化策略: 只需要在一棵索引树上就能获取SQL所需的所有列数据&#xff0c;无需回表&#xff0c;速度更快。 具体的实现方式: 将被查询的字段建立普通索引或者联合索引&#xff0c;这样的话就可以直接返回索引中的的数据&#xff0c;不需要再通过聚…

肖sir__设计测试用例方法之因果图07_(黑盒测试)

设计测试用例方法之因果图 一、定义&#xff1a;因果图提供了一个把规格转化为判定表的系统化方法&#xff0c;从该图中可以产生测试数据。其 中&#xff0c;原因是表示输入条件&#xff0c;结果是对输入执 行的一系列计算后得到的输出。 二、因果图方法最终生成的就是判定表。…