MIKU MOE

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框架要做哪些事情

  1. 将url映射到java类或java类的方法

  2. 封装用户提交的数据

  3. 处理请求--调用相关的业务处理--封装响应数据

  4. 将响应的数据进行渲染 .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配置。

 

 

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

  2. HandlarMapping为处理器映射。DispatcherServlet调用

    HandlerMapping,HandlerMapping根据请求url查找Handler

  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler

  6. Handler让具体的Controller执行

  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名

  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图

  12. 最终视图呈现给用户

 

简搭项目

本项目曾出现过以下问题,原因是导包问题

  • 首先确定导包正确,可以在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 : 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

乱码

  1. 过滤器

  2. 通用配置

复制代码
 <!--配置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;
       }
      复制代码

       



posted @   miku_moe  阅读(46)  评论(0编辑  收藏  举报
编辑推荐:
· 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)
点击右上角即可分享
微信分享提示