SSM_SpringMVC
SSM_SpringMVC
1. MVC
-
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
-
是将业务逻辑、数据、显示分离的方法来组织代码。
-
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
-
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
-
Model(模型)︰数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来: Value Object(数据Dao)和服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
-
View(视图)︰负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
-
Controller(控制器)︰接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。
-
-
最典型的MVC就是JSP + servlet + javabean的模式。
MVC框架要做哪些事情
-
将url映射到java类或java类的方法
-
封装用户提交的数据
-
处理请求--调用相关的业务处理--封装响应数据
-
将响应的数据进行渲染 .jsp/html等表示层数据
- 说明:
-
常见的服务器端MVC框架有 : Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;
-
常见前端MVC框架 : vue、angularjs、react、backbone;
-
由MVC演化出了另外一些模式如 : MVP、MVVM 等等 ...
-
-
Spring MVC的特点 :
-
轻量级,简心易学
-
高效,基于请求响应的MVC框架
-
与Spring兼容性好,无缝结合
-
约定优于配置
-
功能强大 : RESTful、数据验证、格式化、本地化、主题等
-
简洁灵活
-
Spring的web框架围绕DispatcherServlet[调度Servlet]设计。
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。
-
使用SpringMVC必须配置的三大件 :
-
处理器映射器、处理器适配器、视图解析器
-
-
通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即 可,而省去了大段的xml配置。
-
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
-
HandlarMapping为处理器映射。DispatcherServlet调用
HandlerMapping,HandlerMapping根据请求url查找Handler
-
HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器
-
HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等
-
HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
-
Handler让具体的Controller执行
-
Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
-
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
-
DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名
-
视图解析器将解析的逻辑视图名传给DispatcherServlet
-
DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图
-
最终视图呈现给用户
简搭项目
本项目曾出现过以下问题,原因是导包问题
-
首先确定导包正确,可以在maven官网:https://mvnrepository.com/ 搜索
-
确定包正确导入,所有包均存在
-
File-->ProjectStructure-->
-
确认相应项目右边目录下WEB-INF文件夹下存在导入的包
-
如果不存在,则手动创建文件夹"lib",并在上方添加导入所有的包(注意,lib依赖的位置,不在classes文件夹里面)
org.springframework.web.servlet.DispatcherServlet
以下为项目源码:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.9</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies>
web.xml
<?xml version="1.0" encoding="UTF8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatchServlet绑定Spring配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别--> <load-on-startup>1</load-on-startup> </servlet> <!--在Spring中: / /* / :只匹配所有的请求,不会匹配jsp页面 /* :匹配所有请求,包括jsp --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
springmvc-servlet.xml
<?xml version="1.0" encoding="UTF8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--处理器映射器--> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!--处理器适配器--> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!--视图解析器: 模板引擎Thymeleaf Freemarker--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀后缀--> <property name="prefix" value="/WEB-INF/jsp"/> <property name="suffix" value=".jsp"/> </bean> <!--BeanNameUrlHandlerMapping--> <bean id="/hello" class="com.study.controller.HelloController"/> </beans>
test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
HelloController.java
public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result = "helloMVC"; mv.addObject("msg",result); //视图跳转 mv.setViewName("test"); return mv; } }
-
实现接口Controller定义控制器是较老的办法
-
缺点 : 一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller,定义的方式比 较麻烦
注释改写
-
新建一个web项目
-
导入相关jar包
-
编写web.xml ,注册DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置DispatchServlet:这个是SpringMVC的核心;请求分发器,前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatchServlet绑定Spring配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别--> <load-on-startup>1</load-on-startup> </servlet> <!--在Spring中: / /* / :只匹配所有的请求,不会匹配jsp页面 /* :匹配所有请求,包括jsp --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
编写springmvc配置文件
<?xml version="1.0" encoding="UTF8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描包,让指定包下的注解生效,由工OC容器统 管理--> <context:component-scan base-package="com.study.controller"/> <!--Spring MVC不处理静态资源 .css .js .html .mp3 .mp4--> <mvc:default-servlet-handler /> <!-- 支持mvc注解驱动 在spring中一般采用@RequestMapping注解来完成映射关系 要想使@RequestMapping注解生效,必须向上下文中注册: DefaultAnnotationHandLerMapping 和一个AnnotationMethodHandlerAdapter实例 这两个实例分别在类级别和方法级别处理 而annotation-driven配置帮助我们自动完成上述两个实例的注入 --> <mvc:annotation-driven /> <!--视图解析器: 模板引擎Thymeleaf Freemarker--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀后缀--> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp"/> </bean> </beans>
-
接下来就是去创建对应的控制类,controller
/*代表这个类被Spring接管 被这个注解的类中的所有方法,如果返回值是String,并有具体页而可以跳转,那么就会被视图解析器解析 */ @Controller public class HelloController{ @RequestMapping("/hello") public String hello(Model model){ //封装数据 model.addAttribute("msg","Hello"); return "hello";//会被视图解析器处理 } }
-
最后完善前端视图和controller之间的对应
-
测试运行调试
等效注解: @Component 组件 @Service service @Controller controller @Repository dao @ResponseBody //方法使用,它就不会走视图解析器,直接返回字符串 @RestController //类上使用,以下所有方法都直接返回字符串
RestFul风格
/************** 旧风格: .../add?a=1&b=2 ***************/ @RequestMapping("/add") public String test(int a,int b, Model model){ int res=a+b; model.addAttribute("msg","结果为:"+res); return "test" ; //return "test" : 默认为转发 //return "redirect:/test.jsp" : 重定向,请求,如果定义此项,不会走视图解析器 } //Restf /************** RestFul: .../add/a/b ***************/ @RequestMapping("/add/{a}{b}") public String test(@PathVariable int a,@PathVariable int b, Model model){} /************** RestFul:限定方式(默认GET) ***************/ @RequestMapping(value="/add/{a}{b}",method=RequestMethod.DELETE) //简写(常用) @DeleteMapping(/add/{a}{b}) //地址相同可以通过限定提交方式实现不同的功能
重定向和转发
ServletAPl (不建议)
-
通过设置ServletAPl,不需要视图解析器
-
通过HttpServletResponse进行输出
-
通过HttpServletResponse实现重定向
-
通过HttpServletResponse实现转发
SpringMVC
通过SpringMVC来实现转发和重定向-无需视图解析器
//测试前,需要将视图解析器注释掉
//转发一
return "WE B-INF/index.jsp";
//转发二
return "forward:/WEB-INF/index.jsp";
//重定向
return "redirect:/index.jsp";
参数请求回显
接收
@Controller @RequestMapping("/user") public class UserController { /*localhost:808e/user/t1 ? username=xxx; public String test1(String name,Model model) 在这种情况下不管传入的传输名是什么都会转跳,名字不一样则数据为空 @RequestParam如果表明名字,则说明此数据从前端获取,且数据名不能错,数据名不一致直接报错 */ @GetMapping("/t1") public String test1(@RequestParam("username")String name,Model model){ //1.接收前端参数 System.out.println("接收到前端的参数为: "+name); //2.将返回的结果传递给前端,Model model.addAttribute( "msg" ,name ); //3.视图跳转 return "test"; }
//前端按收的是一个对象: id. name. age /* 1.接收前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用 2.假设传递的是一个对象User,匹配User对象中的字段名,如果名字一致则OK,否则,匹配不到 */ @GetMapping("/t2") public String test2(User user){ System.out.println(user); return "test"; } }
回显
-
ModelAndView
-
Model
-
ModelMap
Model : 有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解
ModelMap : 继承了LinkedMNap ,除了实现了自身的一些方法,同样的继承LinkedMap 的方法和特性
ModelAndview : 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
乱码
-
过滤器
-
通用配置
<!--配置SpringMVC的乱码过滤,固定写法--> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.characterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <ur1-pattern>/</ur1-pattern> </filter-mapping>
JSON
前后端分离时代:
后端部署后端,提供接口,提供数据:
json
前端独立部署,负责渲染后端的数据:
JSON(JavaScript Object Notation , JS对象标记)是一种轻量级的数据交换格式,目前使用特别广泛。
-
采用完全独立于编程语言的文本格式来存储和表示数据。
-
简洁和清晰的层次结构使得JSON成为理想的数据交换语言。
-
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JavaScript语言中,一切都是对象。因此,任何JavaScript支持的类型都可以通过JSON来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
-
对象表示为键值对,数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
JSON键值对是用来保存JavaScript对象的一种方式,和JavaScript对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号""包裹,使用冒号:分隔,然后紧接着值.
JSON和JavaScript对象互转
//要实现从JSON字符串转换为JavaScript对象,使用JSON.parse()方法: var obj JSON.parse('{"a":"Hello","b":"world"}'); //结果是{a:'Hello',b:'world'} //要实现从JavaScript对象转换为JSON字符串,使用JSON.stringify()方法: var json = JSON.stringify({a:'Hello',b:'world'}); //结果是'{"a":"Hello","b":"wor1d"}'
Controller返回JSON数据
-
Jackson 应该是目前比较好的json解析工具了
-
当然工具不止这一个,比如还有阿里巴巴的fastjson等等。
-
我们这里使用Jackson,使用它需要导入它的jar包;
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.0</version> </dependency>
-
配置 web.xml 固定写法
<?xml version="1.0" encoding="UTF8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--注册Servlet--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--通过初始化参数指定SpringMVC配置文件位置,进行关联--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--过滤器--> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.characterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <ur1-pattern>/</ur1-pattern> </filter-mapping> </web-app>
-
springmvc-config.xml
<?xml version="1.0" encoding="UTF8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描包,让指定包下的注解生效,由工OC容器统 管理--> <context:component-scan base-package="com.study.controller"/> <!--JSON乱码问题配置--> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter") <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson20bjectNapperFactoryBean"> <property name="fail0nEmptyBeans" value="false" /> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--Spring MVC不处理静态资源 <mvc:default-servlet-handler />--> <!--支持mvc注解驱动 <mvc:annotation-driven />--> <!--视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀后缀--> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp"/> </bean> </beans>
-
User
-
UserController
//@RequestMapping(value="/j",produces="application/json;charset=utf-8")乱码解析(用的少) @RequestMapping("/j") @ResponseBody //不走视图解析器,直接返回一个字符串 public String json( ) throws JsonProcessingException { //jackson ObjectMapper ObjectMapper mapper = new ObjectMapper(); //创建一个对象 User user = new User("name",3,"man"); String str = mapper.writeValueAsString(user); //如果是数组,格式为[{"key":"value","key":"value",...},{},{},...] /* 如果是时间,默认格式为Timestamp(时间戳) 时间设置格式1(Java): SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return mapper.writeValueAsString(sdf.format(date); 时间设置格式2(ObjectMapper): ObjectMapper mapper = new 0bjectMapper(); 不使用时问戳 mapper.configure(SerializationFeature.WRITE_DATES_AS_TINESTAMPS,false); SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); return mapper.writevalueAsString(date); */ return str; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)