SpringMVC学习
SpringMVC学习
概论
Spring MVC是一个Java框架,用于构建Web应用程序。它遵循Model-View-Controller设计模式。它实现了核心Spring框架的所有基本功能,例如控制反转,依赖注入。
Spring MVC通过 DispatcherServlet 提供了一种优雅的解决方案,可以在Spring框架中使用MVC。在这里, DispatcherServlet 是一个类,用于接收传入的请求并将其映射到正确的资源,例如控制器,模型和视图。
Spring MVC 的实现步骤
- 创建 web 应用。
- 加入 web 依赖,如 Spring-webmvc 和 servlet 依赖。
- 声明 springmvc 核心对象 DispatcherServlet。
- 创建一个 jsp,发起请求。
- 创建一个普通类,作为控制器使用,代替之前的 servlet。
- 创建显示处理结果的 jsp 页面。
- 创建 springmvc 的配置文件。
通过以上步骤,可以实现一个简单的 Spring MVC 应用,并利用其强大的功能和灵活的架构进行 web 开发。流程如下图所示:

Spring MVC Framework的优点
让我们看看Spring MVC Framework的一些优点:
分离角色-Spring MVC分离每个角色,其中可以由专门的对象来实现模型对象,控制器,命令对象,视图解析器,DispatcherServlet,验证器等。
轻量-它使用轻巧的servlet容器来开发和部署您的应用程序。
强大的配置-它为框架和应用程序类提供了可靠的配置,其中包括跨上下文的轻松引用,例如从Web控制器到业务对象和验证器。
快速开发-Spring MVC促进了快速并行的开发。
可重复使用的业务代码-无需创建新对象,它使我们可以使用现有业务对象。
易于测试-在Spring中,通常我们创建JavaBeans类,使您可以使用setter方法注入测试数据。
灵活的映射-它提供了可轻松重定向页面的特定注释。
代码实现
在这之前写一个连接数据库的bean,这个在MySQL篇写到,可在主页寻找知识。
引入依赖
<!--引入了MVC的依赖 包含了IoC的内容-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
配置类application.yaml
server:
# 配置tomcat的端口号 默认是8080
port: 8001
# 配置项目的web路径
servlet:
context-path: / #名字,默认/
spring:
application:
# 给项目起了一个名字
name: boot-mvc
mvc:
view:
suffix: .html #因为我的前端用html演示效果,在下面书写controller里a不用加后缀
prefix: / #controller里a是根的a.html
书写一个简单的前端界面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是首页
<a href="/first/a">访问FirstController的a方法</a>
<a href="first/b">访问FirstController的b方法</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>a.html</h3>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>b.html</h3>
</body>
</html>
页面跳转
书写controller(入门)
import jakarta.servlet.annotation.WebServlet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Slf4j
// 类似于servlet
// new对象
@Controller
// 设置web路径
// @WebServlet("/first")
@RequestMapping(value = "/first")
public class FirstController {
// http://localhost:8001/first/a
@RequestMapping(value = "/a")
public String a(){
log.info("用户访问了FirstController的a方法!");
// 响应 要跳转到哪里去 a
return "a";
}
// 缩写形式
@RequestMapping("/b")
public String b(){
log.info("用户访问了FirstController的b方法!");
// 响应 要跳转到哪里去 b
return "b";
}
}
书写启动类并启动
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BootMVCApplication {
public static void main(String[] args) {
SpringApplication.run(BootMVCApplication.class,args);
}
}
在浏览器输入路径访问,并且点击跳转

传参操作
书写controller
import com.jiazhong.boot.commons.bean.Users;
import lombok.extern.slf4j.Slf4j;
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;
// 参数传递问题
@Slf4j
@Controller
@RequestMapping("/second")
public class SecondController {
@RequestMapping("/a")
public String a(String name) {
log.info("用户访问了SecondController的a方法!");
log.info("name:{}", name);
return "a";
}
}
启动后浏览器访问

@RequestMapping("/b")
public String b(@RequestParam(name = "page", defaultValue = "1") int p) { //如果没传值,默认为1
log.info("用户访问了SecondController的b方法!");
log.info("页码:{}", p);
return "a";
}

@RequestMapping("/c")
public String c(String name, int age, char gender) {
log.info("用户访问了SecondController的c方法!");
log.info("name:{},age:{},gender:{}", name, age, gender);
return "a";
}

@RequestMapping("/d")
public String d1(Users user) {
log.info("用户访问了SecondController的d1方法!");
log.info("user:{}", user);
return "a";
}

获取值和重定向
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.io.IOException;
import java.io.PrintWriter;
@Slf4j
@Controller
@RequestMapping("/third")
public class ThirdController {
@RequestMapping("/a") //重定向
public String a() {
log.info("用户访问了ThirdController的a方法!");
return "redirect:/a.html";
}
@RequestMapping("/b") //获取值
public String b(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
PrintWriter out = response.getWriter();
log.info("request:{}", request);
log.info("response:{}", response);
log.info("session:{}", session);
log.info("application:{}", application);
log.info("out:{}", out);
log.info("用户访问了ThirdController的b方法!");
return "redirect:/a.html";
}
}
注意:post、put、delete请求要用Apipost(一个测试的软件)测
数据返回
import com.jiazhong.boot.commons.bean.Users;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Controller
@RequestMapping("/fourth")
public class FourthController {
@RequestMapping("/a")
public void a(HttpServletResponse response) throws IOException {
log.info("用户访问了FourthController的a方法");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("Hello,world!");
}
@RequestMapping("/b")
@ResponseBody // 告诉服务器,这里的返回结果不再是页面跳转,而是数据的输出
public String b() {
log.info("用户访问了FourthController的b方法");
return "Hello,world!";
}
@RequestMapping(value = "/c", produces = {"application/json;charset=utf-8"})
@ResponseBody
public Users c() { //返回对象
log.info("用户访问了FourthController的c方法");
Users users = new Users();
users.setId(1);
users.setName("张三");
users.setAge(29);
users.setGender('男');
return users;
}
@RequestMapping("/d")
@ResponseBody
public List<Users> d() { //返回集合
log.info("用户访问了FourthController的d方法");
Users u1 = new Users(1, "张三", 23, '男');
Users u2 = new Users(2, "李四", 21, '女');
Users u3 = new Users(3, "王五", 26, '男');
Users u4 = new Users(4, "马六", 25, '男');
List<Users> list = Arrays.asList(u1, u2, u3, u4);
return list;
}
}
指定返回类型(Get、Post、Put、Delete)
import com.jiazhong.boot.commons.bean.Users;
import com.jiazhong.boot.commons.util.JsonResult;
import com.jiazhong.boot.commons.util.ResultTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
// 当前类的所有请求,都允许其他项目访问
@CrossOrigin
@Slf4j
// @Controller+@ResponseBody
@RestController
@RequestMapping("/fifth")
public class FifthController {
// @RequestMapping(value = "/a", method = RequestMethod.GET)
// @GetMapping("/a")
@GetMapping
public JsonResult a() {
log.info("用户访问了FifthController的a方法");
return ResultTool.success("用户访问了FifthController的a方法");
}
@PostMapping
public JsonResult b(String name, int age) {
log.info("用户访问了FifthController的b方法");
log.info("name:{},age:{}", name, age);
return ResultTool.success("用户访问了FifthController的b方法");
}
@PostMapping("/c1")
public JsonResult c1(Users user) {
log.info("用户访问了FifthController的c1方法");
log.info("user:{}", user);
return ResultTool.success("用户访问了FifthController的c1方法");
}
@PostMapping("/c2")
public JsonResult c2(@RequestBody Users user) {
log.info("用户访问了FifthController的c2方法");
log.info("user:{}", user);
return ResultTool.success("用户访问了FifthController的c2方法");
}
@PutMapping("/d")
public JsonResult d(Users user) {
log.info("用户访问了FifthController的d方法");
log.info("user:{}", user);
return ResultTool.success("用户访问了FifthController的d方法");
}
@DeleteMapping("/e")
public JsonResult e(Users user){
log.info("用户访问了FifthController的e方法");
log.info("user:{}", user);
return ResultTool.success("用户访问了FifthController的e方法");
}
}
另外的传参方式
import com.jiazhong.boot.commons.util.JsonResult;
import com.jiazhong.boot.commons.util.ResultTool;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// Restful风格
@RestController
@RequestMapping("/sixth")
public class SixthController {
// http://localhost:8001/sixth
@GetMapping
public JsonResult a() {
return ResultTool.success("a");
}
// 过去:http://localhost:8001/sixth/b?name=admin
// 现在:http://localhost:8001/sixth/b/admin
@GetMapping("/b/{name}")
public JsonResult b(@PathVariable("name") String name) {
return ResultTool.success(name);
}
@GetMapping("/c/{name}/{age}")
public JsonResult c(@PathVariable("name") String name, @PathVariable("age") int age) {
return ResultTool.success(name + ".." + age);
}
// 不在另外演示post、put以及delete
}
获取请求头(header)
import com.jiazhong.boot.commons.util.JsonResult;
import com.jiazhong.boot.commons.util.ResultTool;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin
@Slf4j
@RestController
@RequestMapping("/seventh")
public class SeventhController {
@GetMapping
public JsonResult execute(HttpServletRequest request) {
String token = request.getHeader("token");
log.info("token:{}", token);
return ResultTool.success(token);
}
}
前后端分离实现
用HBuilderX或者WebStorm来书写前端代码
前端代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<button @click="funA">调用a方法</button>
<hr />
<input v-model="name" />
<input v-model="age" />
<button @click="funB">调用b方法</button>
<hr />
<input v-model="name" />
<input v-model="age" />
<button @click="funC">调用c方法</button>
<hr />
<input v-model="name" />
<input v-model="age" />
<button @click="funD">调用d方法</button>
<hr />
<button @click="funE">调用e方法</button>
</div>
</body>
</html>
<script src="../js/vue.min.js"></script>
<script src="../js/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
name: '',
age: ''
}
},
methods: {
funA() {
axios({
method: "get",
url: "http://localhost:8001/fifth"
}).then(resp => {
console.log(resp.data)
})
},
funB() {
let data = new URLSearchParams()
data.append('name', this.name)
data.append('age', this.age)
axios({
method: 'post',
url: "http://localhost:8001/fifth",
data: data
}).then(resp => {
console.log(resp.data)
})
},
funC() {
let data = new URLSearchParams()
data.append('name', this.name)
data.append('age', this.age)
axios({
method: 'put',
url: "http://localhost:8001/fifth/d",
data: data
}).then(resp => {
console.log(resp.data)
})
},
funD() {
axios({
method: 'delete',
url: "http://localhost:8001/fifth/e",
params: {
name: this.name,
age: this.age
}
}).then(resp => {
console.log(resp.data)
})
},
funE(){
axios({
method:'get',
url:'http://localhost:8001/seventh',
headers:{
token:'egrdjksgu21ekjdsfksggfjkv'
}
}).then(resp=>{
console.log(resp.data)
})
}
}
})
</script>
允许跨域方式
1.在controller里加注解@Controller(局部)
当前类的所有请求,都允许其他项目方法
2.书写一个跨域配置类config(全局)
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口都允许跨域
.allowedOriginPatterns("*") // 允许所有域名(SpringBoot 2.4+ 用这个)
.allowCredentials(true) // 允许携带Cookie
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方式
.maxAge(3600); // 预检请求有效期(秒)
}
}
3.注册一个CorsFilter 过滤器(全局)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsFilterConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*"); // 允许所有域名
config.setAllowCredentials(true);
config.addAllowedMethod("*"); // 允许所有请求方式
config.addAllowedHeader("*"); // 允许所有请求头
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 匹配所有接口
return new CorsFilter(source);
}
}
4.网关统一配置application.yaml(微服务场景)
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origin-patterns: "*"
allowed-headers: "*"
allowed-methods: "*"
allow-credentials: true
MVC与拦截器实现
拦截器实现步骤
1.实现一个方法HandlerInterceptor
2.重写里面的方法(一去二回)
3.注册拦截器(config)
书写controller
import com.jiazhong.boot.commons.util.JsonResult;
import com.jiazhong.boot.commons.util.ResultTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/first")
public class FirstController {
@GetMapping("/a")
public JsonResult a(){
log.info("This is FirstController a method");
return ResultTool.success("This is FirstController a method");
}
@GetMapping("/b")
public JsonResult b(){
log.info("This is FirstController b method");
return ResultTool.success("This is FirstController b method");
}
}
书写拦截器
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class FirstInterceptor implements HandlerInterceptor {
//去的方法 过滤的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("This is FirstInterceptor preHandle");
return true;//true表示放行,false表示拦截
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("This is FirstInterceptor postHandle");//回的
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("This is FirstInterceptor afterCompletion");//回的
}
}
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class SecondInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("This is SecondInterceptor preHandle");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("This is SecondInterceptor postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("This is SecondInterceptor afterCompletion");
}
}
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
@Slf4j
public class ThirdInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("This is ThirdInterceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("This is ThirdInterceptor postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("This is ThirdInterceptor afterCompletion");
}
}
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
@Slf4j
public class FourthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("This is FourthInterceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("This is FourthInterceptor postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("This is FourthInterceptor afterCompletion");
}
}
注册拦截器
import com.jiazhong.spring.boot.mvc.interceptor.interceptor.FirstInterceptor;
import com.jiazhong.spring.boot.mvc.interceptor.interceptor.FourthInterceptor;
import com.jiazhong.spring.boot.mvc.interceptor.interceptor.SecondInterceptor;
import com.jiazhong.spring.boot.mvc.interceptor.interceptor.ThirdInterceptor;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 对MVC进行配置的一个Configuration
@Configuration
public class SpringMVCConfig implements WebMvcConfigurer {
@Resource
private FirstInterceptor firstInterceptor;
@Resource
private SecondInterceptor secondInterceptor;
@Resource
private ThirdInterceptor thirdInterceptor;
@Resource
private FourthInterceptor fourthInterceptor;
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册了拦截器并设置对哪些请求进行拦截
registry.addInterceptor(firstInterceptor)
.addPathPatterns("/first/**")
.excludePathPatterns("/first/a").order(1);
registry.addInterceptor(secondInterceptor)
.addPathPatterns("/**").order(7);
registry.addInterceptor(thirdInterceptor)
.addPathPatterns("/**").order(98);
registry.addInterceptor(fourthInterceptor)
.addPathPatterns("/**").order(3);
}
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)