猿蜕变4——一文获取web框架正确学习套路

时间:2022-07-22
本文章向大家介绍猿蜕变4——一文获取web框架正确学习套路,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

看过之前的springMVC初体验,相信你对springMVC有了一定的认识。今天我们继续来学习springMVC相关的核心知识,掌握web框架的正确学习办法,帮助你快速起飞,完成蜕变。

在这章节之前,我们已经编写了第一个SpringMVC的程序—HelloSpringWebMVC,也对它做了简单的流程分析,实际上SpringMVC还有其他的执行流程,下面这幅图,就是springMVC的执行流程图:

0.在应用启动时,我们配置的前端控制器DispatcherServlet加载spring MVC相关的配置文件,完成应用的初始化工作,这个事情只会在应用启动时做一次,。

1.用户发起请求http://127.0.0.1/helloWebMvc.do,所有满足DispatcherServlet 的URL规则的请求,都会被匹配转发到DispatcherServlet。

2.DispatcherServlet将Url交由处理器映射器(HandlerMapping)处理。

3. 处理器映射器(HandlerMapping)会返回一个执行链(这个请求需要执行哪些步骤,包括公共部分和我们自己编写的Controller)给DispatcherServlet。

4. DispatcherServlet根据之前返回的执行链,再次请求处理适配器(HandlerAdper)。

5. 处理适配器(HandlerAdper)将执行链交由相匹配的处理器(Handler)执行。

6. 处理器(Handler)执行具体的处理流程并且返回ModelAndView对象

7. 处理适配器(HandlerAdper)将处理器(Handler)返回的ModelAndView对象返回给前端控制器DispatcherServlet。

8. 前端控制器DispatcherServlet请求视图解析器(ViewResolver)查找对应的视图。

9. 视图解析器(ViewResolver)将对应的视图对象(View)返回给前端控制器DispatcherServlet

10.前端控制器将视图对象(View)转发给对应的视图组件。视图组件(比如jsp、velocity等等具体的视图组件)完成渲染工作,将渲染结果(很多时候是HTML文档)返回给前端控制器DispatcherServlet。

11. 前端控制器DispatcherServlet将最后的结果返回给用户(浏览器)。

配置url-pattern为*.do,这个是最常用的方式,其实你要是配置为*.xxx都是可以的,只要url能匹配,没什么问题,程序可以执行,但是,很多时候可能习惯成自然,大家都这么干,你也就必须这么干,因为在中国大家是最厉害的群体,不敢轻易得罪,得罪了容易没饭吃啦。

如果将url-pattern配置为/*,那么所有的请求都会到达DispatcherServlet,如果你直接请求一个jsp页面,也会被当作是一个Controller去处理,而DispatcherServlet找不到你请求的jsp页面(因为它会认为你请求的是一个Controller),就会造成404错误。所以在实际的开发过程中,最好不要去做/*的配置

如果将url-pattern配置为/,那么应用中涉及的静态资源:比如html页面、css文件、js文件、图片等等,都会交由DispatcherServlet处理。这种配置方式不会拦截.jsp文件和.jspx文件,因为这个在tomcat中的conf目录里面的web.xml文件中已经做了相关配置处理,这些请求会交给org.apache.jasper.servlet.JspServlet去处理,能够正常的访问到jsp页面。

解决静态资源不能访问的问题,解决方式有三种:

使用defaultServlet:

在tomcat中的conf/web.xml中配置,增加一个DefaultServlet的配置,当某个请求系统找不到由谁去处理时,就会让DefaultServlet去处理。我们可以DefaultServlet去处理静态资源,如果你要配置在应用中配置也是可以的,只是由一个要求:必须配置在DispatcherServlet之前:

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.jpg</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.css</url-pattern>
</servlet-mapping>

使用mvc:default-servlet-handler:

在Spring MVC的配置文件中(spring-servlet.xml)增加配置即可,这种方式会将所有的请求交由对应的servlet进行处理,当然,最终也是由DefaultServlet来处理:

<mvc:default-servlet-handler/>

使用mvc:resources:

SpringMVC提供了mvc:resources标签来专门解决解决静态资源无法访问的问题,只需要在Spring MVC的配置文件中(spring-servlet.xml)增加以下配置即可,这样这些静态资源会交给Spring MVC提供的ResourceHttpRequestHandler进行处理:

<mvc:resourcesmapping="/static/**" location="/ static /" />

mapping表示对静态资源url请求的要求。需要特别注意的是,/后是两个星号**。

location表示静态资源存放的目录,这个路径是一个相对路径,相对于应用的webapp目录的一个路径,要求资源位于webapp目录下,我们配置成了/ static /,所以我们可以在应用的webapp目录下创建一个static文件夹,然以后将所有的静态资源放进去,一般来说我们对静态文件需要做下分类,所以会在static目录下再建立子目录:css,js,images,分别存放css文件,js文件,和图片。推荐使用该配置。

我们之前编写Spring MVC 程序,需要在spring-servlet.xml中配置我们的Controller,比如:

<bean id="/helloWebMvc.do"class="com.pz.web.study.springmvc.controller.HelloSpringWebMVC"/>

随着我们需要开发的功能增加,我们会编写更多的Controller,这样一来,每增加一个Controller,我们就需要增加一行类似的配置,spring-servlet.xml就会越来越大,慢慢的变得难以维护。,而实际上,Spring MVC提供了基于注解的方式来解决这个问题,让配置文件变得更加简洁明了。接下来,我们就使用注解的方式来编写我们的Controller。

使用注解编写spring MVC 的Controller程序,和使用配置文件的方式基本一致,也需要在web.xml配置DispatherServlet(咱们之前已经加过了,暂时不用动了)。我们需要在对SpringMVC的配置文件做一些修改就好:

配置组件扫描器

我们在配置文件中增加组件扫描器就好了。修改spring-servlet.xml配置文件,增加配置:

<!-- 自动扫描com.pz.web.study.springmvc.controller路径下的所有文件,并根据注解完成注入的工作 -->
      <context:component-scan base-package="com.pz.web.study.springmvc.controller.*"></context:component-scan>

以上配置增加以后,在应用启动时,SpringMVC 会扫描com.pz.web.study.springmvc.controller包下所有类,并对所有增加了Spring MVC 能够识别的Controller的Annotation的类做实例化操作(大家想想咱的小框架,是不是很类似?)。

配置注解驱动(如果你使用了mvc:resources标签就需要增加这个配置,要不会有404错误)

修改spring-servlet.xml配置文件,增加配置:

<mvc:annotation-driven/>

编写Controller代码在com.pz.web.study.springmvc.controller包下创建AnnotationControllerDemo类:

package com.pz.web.study.springmvc.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
 
@Controller
public class AnnotationControllerDemo {
      
       @RequestMapping("/helloByAnnotation.do")
       public ModelAndViewhelloAnnotation(HttpServletRequest req, HttpServletResponse res) throws Exception {
             
               ModelAndView mv = new ModelAndView();
           mv.addObject("hello", "hello spring web mvc by helloAnnotation");
           mv.setViewName("helloByAnnotation");
           return mv;
        }
 
}

编写页面代码helloByAnnotation.jsp,测试页面嘛可以简单点,启动tomcat,我们访问下:

http://127.0.0.1/helloByAnnotation.do页面输出

hello spring web mvc by helloAnnotation

我们打开之前编写的AnnotationControllerDemo类,这类没有实现任何接口,只是在类名和方法上添加了两个注解:

@Controller(需要引入org.springframework.stereotype.Controller):使用在类名上,表示是一个Controller。

@RequestMapping(需要引入org.springframework.web.bind.annotation.RequestMapping):使用在方法上,表示该方法为Controller提供的方法,属性值value,为一个URI,表示这个方法响应对应的URL,这个URL是一个相对路径,相对于webapp,方法名可以随意命名。一个方法也可以处理多个请求,只用定义多个url就好。 @RequestMapping也可以被使用在类名上,表示这个Controller类下的所有方法,都属于一个目录。当@RequestMapping被使用在类名上时,方法上的@RequestMapping就相对于类名上定义的路径。为了加深大家的理解我们看下面的例子。

package com.pz.web.study.springmvc.controller;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
 
@Controller
@RequestMapping("/demo/")
publicclass AnnotationControllerDemo2 {
      
       @RequestMapping("/hello.do")
       public ModelAndView hello(HttpServletRequest req,HttpServletResponse res) throws Exception{
             
               ModelAndView mv = new ModelAndView();
           mv.addObject("hello", "hello spring web mvc by helloAnnotation");
           mv.setViewName("helloByAnnotation");
           return mv;
        }
      
      
       @RequestMapping({"/hello2.do","/hello3.do"})
       public ModelAndView hello2(HttpServletRequest req,HttpServletResponse res) throws Exception{
             
               ModelAndView mv = new ModelAndView();
           mv.addObject("hello", "one method for multiple urls");
           mv.setViewName("helloByAnnotation");
           return mv;
        }
 
      
      
 
 
}

启动tomcat分别访问:

http://127.0.0.1/demo/hello.do

http://127.0.0.1/demo/hello2.do

http://127.0.0.1/demo/hello3.do