SpringMVC(二)

    科技2022-07-31  86

    SpringMVC(二)

    快速入门(IDEA版无注解)原理细解原理深入处理器映射器处理器适配器视图解析器 小结

    快速入门(IDEA版无注解)

    IDEA建立Maven项目后,添加web框架后,导入以下的jar依赖

    <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</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>

    随后,手动配置注册Servlet,如下

    <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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>

    再在resources目录下创建xml文件(起到SpringIOC容器的作用),文件名要和web.xml中<init-param>的value值 如web.xml中写的springmvc-servlet.xml名中添加bean组件如下

    添加处理映射器 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> 添加处理器适配器 <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> 添加视图解析器 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> 添加Controller自定义类 <bean id="/hello" class="controlller.MyController"/>

    这里,id就是用户请求的url最后的请求

    然后在java中新建类com.sang.controller.MyController

    package com.sang.controlller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //ModelAndView 模型和视图 ModelAndView mv = new ModelAndView(); //封装对象,放在ModelAndView中。Model mv.addObject("msg","HelloSpringMVC!"); //封装要跳转的视图,放在ModelAndView中 mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp return mv; } }

    ModelAndView 是一个类,表示模型和视图,返回给DispatcherServlet前端控制器,这里传递了一个msg的变量,值为字符串“HelloSpringMVC!",viewName是hello.jsp,随后会讲解原理

    在WEB-INF下新建目录jsp,在里面新建hello.jsp前端页面,这里就写上如下

    <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>

    然后部署Tomcat中后,启动服务器,访问localhost:8080/springmvc-01/hello 结果如下:

    原理细解

    先看如下的图: 首先 用户通过url访问服务器

    URL形如(127.0.0.1:8080)/(springmvc-01)/(hello)

    第一个括号是服务器的ip第二个括号是服务器的项目第三个括号是一系列的请求

    我们在web.xml中写了如下映射

    <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

    意思就是所有请求都会去找名为springmvc的servlet,而这个servlet的注册就是对应DispatcherServlet这个类,这个中央控制器(又称前端控制器)会将请求/hello交给处理器映射器,映射器(HandlerMapping)会把请求映射为HandlerExecutionChain类型的handler对象交给这个中央控制器;然后中央处理器将handler对象作为参数传递给适配器(HandlerAdapter)的实例化对象,适配器对其进行处理,还会调用其他模型层最后返回ModelAndView给中央处理器。

    处理器映射器,处理器适配器,这两个类我们在web.xml中引入了springmvc-servlet.xml的SpringIOC容器,在这个容器中我们注册有处理器映射器和处理器适配器

    细看我们的controller,它实现了Controller接口,也就是默认为一个处理器,点开观察源码需要实现一个类如下

    ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;

    这个类的返回类型是ModelAndView,意思就是模型和视图,他会携带模型返回给中央处理器,告诉中央处理器模型将要去哪一个视图,于是中央处理器对其进行已经配置一个或多个视图解析器,视图解析器对视图处理,响应给用户,用户最后会得到想要的页面。

    原理深入

    以上讲了大致的流程,我觉得有些细节和深层的知识没有列出,这里总结一下吧 SpringMvc的核心就三个处理器映射器,处理器适配器,视图解析器。

    处理器映射器

    这里我们在IOC里配置的mapping是比较low的,但是比较适合原理解剖。

    BeanNameUrlHandlerMapping 这个类会对请求名在IOC内进行Bean组件的id进行匹配

    然后把请求映射为HandlerExecutionChain类型的handler对象交给中央控制器;可以明确HandlerExecutionChain与HanderMapping关系非常紧密,HandlerExecutionChain只能通过HanderMapping接口中的唯一方法来获得,而我们这里用到的映射器只是其中一个。 注意:映射器不仅仅封装的有handler对象,还封装了拦截器,日后细解。

    处理器适配器

    只需要理解的就是适配器接受了中央处理器传递过来的handler对象,在IOC容器里有注册了的controller,适配器执行的handler对象在我们看来就是执行对应的controller,这里可能会调用其它层,业务层,数据库dao等等,最终都会封装一个ModelAndView类。这个类有Object类和String的视图名,适配器会将这个对象传递给中央处理器。

    视图解析器

    在我们的IOC容器里我们配置了如下图的bean 这bean中配置了prefix和suffix,就是视图的前缀和后缀,ioc会注入的方式给视图解析器赋值,这里我们设置了前缀为/WEB-INF/jsp/意味着我们解析器会在这个项目路径下的这个目录下开始找页面;后缀我们写的是.jsp,意思就是jsp格式的页面;我们在之前的处理器适配器中说到了最红处理器适配器会将ModelAndView这个对象传进中央处理器,然后中央处理器会将这个对象传递给视图解析器,前缀和后缀都规划好了,view的视图名在中间,最终形成完整的视图路径名,ViewResolver就会把该逻辑视图路径解析为真正的View视图对象,然后通过View的渲染,将最终结果返回给中央处理器,然后呈现给用户。

    小结

    今天有同学找我解决问题就是快速建立就会报的404错误,看了代码,都是对的,那就是环境的问题,后来去网上看了一下,lib目录没有导入我们把所有的jar引入即可,IDEA有时会有这个问题。

    原理方面的知识,结合一下图片,就能轻松的解决这些面试基础回答,但是深层的知识还需要进一步去探索,源码的解剖室最为有效的学习方法,我见过有的大牛,自己动手写SpringBoot简易版,当然了,成功的背后总是漫漫长路,我们需要不停的学习和努力!

    Processed: 0.010, SQL: 8