目录
一、SpringMVC常用注解
二、传递参数
2.1 基础类型+String
2.2 复杂类型
2.3 @RequestParam
2.4 @PathVariable
2.5 @RequestBody
2.6 RequestHeader
2.7 请求方法
三、返回值
3.1 void
3.2 String
3.3 String+Model
3.4 ModelAndView
四、页面跳转
4.1 转发
4.2 重定向
五、SpringMVC总结优点与缺点
一、SpringMVC常用注解
1. @Controller:用于声明一个控制器类。
2. @RequestMapping:用于映射请求 URL 到控制器类或处理方法上。
3. @RequestParam:用于获取请求参数的值。
4. @PathVariable:用于获取 URL 中的参数值。
5. @ResponseBody:用于将返回值转化为 JSON 格式或其他格式的数据。
6. @ModelAttribute:用于将请求参数绑定到模型对象上。
7. @Valid:用于验证请求参数。
8. @InitBinder:用于定义数据类型转换和格式化规则。
9. @SessionAttributes:用于将模型对象存储到会话中。
10. @ExceptionHandler:用于处理控制器方法中抛出的异常。
11. @RequestMapping(value=“”, method=RequestMethod.GET) 用于处理 GET 请求。
12. @RequestMapping(value=“”, method=RequestMethod.POST) 用于处理 POST 请求。
13. @RequestMapping(value=“”, method=RequestMethod.PUT) 用于处理 PUT 请求。
14. @RequestMapping(value=“”, method=RequestMethod.DELETE) 用于处理 DELETE 请求。
二、传递参数
2.1 基础类型+String
@RequestMapping("/hello1")
public String toHello1(Integer bid,String bname){
log.info(">>>> 基础类型+String传参:{},{}",bid,bname);
return "index";
}
新建一个paramController类:
package com.Kissship.web;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Kissship
* @site www.Kissship.com
* @company xxx公司
* @create 2023-09-05-14: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";
}
}
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>无需多言</h1>
</body>
</html>
效果演示:
2.2 复杂类型
@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";
}
主页代码不变。
效果演示:
2.3 @RequestParam
@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";
}
在paramController类中添加以下方法:
@RequestMapping("/hello3")
public String hello3(
@RequestParam String bname,
@RequestParam(required = false) Integer bid){
// System.out.println("刘三金去拿奶茶喽。。。");
log.info("@requestParam参数:bname:{},bid:{}",bname,bid);
// fail..error warning info debug
return "index";
}
注:
未加入判断则在域名中必须携带此属性。
主页代码不变。
演示效果:
控制台传参效果:
2.4 @PathVariable
@RequestMapping("/hello4/{bid}")
public String toHello4(@PathVariable("bid") Integer bid){
log.info(">>>> 使用@PathVariable注解传递参数:{}", bid);
return "index";
}
在paramController类中添加以下方法:
@RequestMapping("/hello4/{bid}")
public String hello4(@PathVariable("bid") Integer bid){
// System.out.println("刘三金去拿奶茶喽。。。");
log.info("@requestParam参数:bid:{}",bid);
// fail..error warning info debug
return "index";
}
主页代码不变。
页面演示效果如下:
控制台传参效果:
2.5 @RequestBody
在进行@RequestBody传参前先要在pom.xml传入依赖,如下:
<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>
在导入依赖后我们还需要postman或者apipost/eolink等工具发送请求数据。 因为浏览器发送不了JSON数据请求。所以我们需要安装Eolink等第三方工具进行测试。
安装好后,按照以下步骤把参数填写好,query参数是往域名链接添加属性,如下:
然后介绍完Query参数后就开始添加我们的请求体参数,如下:
输入请求参数后,我们先测试hello5,看能否传过去,如下:
通过方法五跟方法六的对比,可得出@RequestBody适用于专门接受Json数据形式串。
2.6 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";
}
代码完成之后我们需要在Eolink中进行头部请求参数配置,如下:
然后进行测试(方法七)结果如下:
最后我们再来测试以下方法八,个人配置如下:
2.7 请求方法
请求方法有:
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.Kissship.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.Kissship.web;
import com.Kissship.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 Kissship
* @site www.Kissship.com
* @company xxx公司
* @create 2023-09-05-14: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("舞者","增加成功!!!");
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>敢爱敢做</h1>
歌词上句: ${No1}<br>
歌词下句: ${No2}
</body>
</html>
3.1 void
处理器对请求处理后,无需跳转到其它任何资源,此时可以让处理器方法返回 void。
3.2 String
3.3 String+Model
打开浏览器输入相对应地址,结果如下:
Model测试:
将test03换成test04接着输出即可:
3.4 ModelAndView
打开浏览器输入相应请求地址,结果如下:
四、页面跳转
创建一个PathConterller测试类,进行页面跳转的各种方法测试,代码如下:
package com.Kissship.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 Kissship
* @site www.Kissship.com
* @company xxx公司
* @create 2023-09-06-16: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";
}
}
4.1 转发
它相当于“request.getRequestDispatcher("url").forward(request,response)”。使用转发,既可以转发到jsp, 也可以转发到其他的控制器方法。
打开服务器 ,在浏览器上方输入对应请求地址此处输入Demo02,结果如下:
4.2 重定向
打开服务器 ,在浏览器上方输入对应请求地址此处输入Demo04,结果如下:
五、SpringMVC总结优点与缺点
优点:
- 简化配置:注解可以替代繁琐的XML配置,使配置更加简洁和直观。注解使用注解处理器进行解析,可以自动完成配置和初始化的工作,减少了手动配置的工作量。
- 提高可读性:通过使用注解,开发人员可以更清晰地了解代码的作用和意图。注解的语义明确,可以提高代码的可读性和可维护性。
- 提高开发效率:注解简化了很多重复性的工作,如依赖注入、请求映射等。开发人员可以专注于核心业务逻辑而不必关注繁琐的配置细节,从而提高开发效率。
- 提供丰富的功能扩展:Spring框架提供了多种注解,可以应用于不同的场景和功能需求,如控制器的请求映射、数据验证、事务管理等。这些注解提供了灵活的扩展机制,使得开发人员可以根据具体需求进行定制化的开发。
- 支持AOP:Spring框架通过注解提供了对面向切面编程(AOP)的支持。使用注解修饰目标方法或类,可以方便地定义切点、切面和通知,提供横切关注点的解耦和重用能力。
缺点:
- 隐式依赖:注解的使用可能导致隐式依赖,不像显式配置那样清晰可见。有时候可能会造成代码的可读性和维护性下降,特别是在大型项目中。
- 学习成本:使用注解需要对注解的语法和规范有一定的了解和掌握。不熟悉注解的开发人员可能需要花费一些时间学习和适应。
- 自定义性受限:某些注解的功能和行为是固定的,如果需要自定义一些特定的逻辑,可能需要编写额外的代码或使用其他方式实现。
- 过度使用:过度使用注解可能导致代码变得难以理解和维护。在使用注解时,应该遵循适度使用的原则,确保注解的使用符合代码的整体设计思路和架构。
最后SpringMVC综合案例就到这里,祝大家在敲代码的路上一路通畅!