第一个springmvc项目

cho1-hello-springmvc:第一个springmvc项目

一. 需求:

用户在页面发起一个请求,请求交给springmvc的控制器对象,并显示请求的处理结果(在结果页面显示一个欢迎语句)。

二. 实现步骤:

  1. 新建web maven工程(main包下添加java包和resources包,然后修改web.xml文件的版本)

  2. 加入依赖,

    1)spring-webmvc依赖,也就间接把spring的依赖都加入倒项目,

    2)jsp,servlet依赖**(为什么没有jsp依赖?)**

  3. 重点:在web.xml项目中注册springmvc框架的核心对象DispatcherServlet(dispatcher英文:分配器)

    1)DispatchServlet叫做中央调度器,是一个servlet,他的弗雷是继承HttpServlet.

    2)DispatchServlet也叫做前端控制器(front controller)

    3)DispatcherServlet负责接收用户提交的请求,调用其他的控制器对象,并把请求的处理结果显示给用户。

  4. 创建一个发起请求的页面 index.jsp。

  5. 创建控制器类

    1)在类的上面加@Controller注解,创建对象,并放入倒springmvc容器中。

    2)在类的方法上面加入@RequestMapping注解。

  6. 创建一个作为结果的jsp,显示请求的处理结果。

  7. 创建spring的配置文件(spring的配置文件一样)。

    1)声明组件扫面器,指定@Controller注解所在的包名。

    2)声明视图解析器,帮忙处理视图的。

文件访问流程:

  1. 请求(index.jsp文件)
  2. *.do(web.xml文件)
  3. springmvc(web.xml文件)
  4. 中央调度器org.springframework.web.servlet.DispatcherServlet(web.xml文件)
  5. classpath:springmvc.xml(web.xml文件)
  6. 组件扫描器(resources包下的springmvc.xml文件)组件扫描器中的实体类(控制器类Mycontroller类)
  7. 通过RequestMapping请求映射注解的属性可以得知相对应的“servlet"方法,“servlet"方法类似javaWeb中的doGet()方法
  8. 展示界面(show.jsp文件)

三. 源码及注释(代码知识点讲解):

1. web.xml文件("/" 和 " *.do "

这个xml文件需要更换版本

<!--
	声明,注册springmvc的核心对象DispatcherServlet
	需要在tomcat服务器启动后,创建DispatcherServlet对象实例,也就是下面的控制顺序的标签,
	但是为什么要创建DispatcherServlet对象的实例呢?
	DispatcherServlet在他的创建过程中,会同时创建springmvc容器对象,读取springmvc的配置文件,把这个配置文件	 中的对象都创建好,当用户发起请求是法就可以直接使用对象。
	servlet的初始化会指向init()方法。DispatcherServlet在init()中{
		//创建容器,读取配置文件
		WebApplicationContext ctx = new ClasspathXmlApplicationContext("springmvc.xml")
	}
-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
<!--自定义springmvc读取的配置文件的位置-->
    <init-param>
    <!--springmvc的配置文件的位置的属性-->
        <param-name>contextConfigLocation</param-name>
    <!--指定自定义文件的位置-->
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    
<!--
	在tomcat启动后,创建Servlet对象
	load-on-startup:表示tomcat启动后创建安对昂的顺序,原本是在servlet被访问时创建DispatcherServlet中央调度	  器对象。它的值是整数,数值越小,tomcat创建对象的时间越早。
-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
<!--
  使用框架是,url-pattern可以使用两种值
 1.使用框架扩展名,语法 *.xxxx,xxxx是自定义扩展名,常用,*.do等,不能用*.jsp(不用加/)
 2.使用"/"。表示中央调度器加载所有资源请求包括静态资源,和为映射到其他servlet的请求等(原本是交给tomcat处理的可查看tomcat中的web.xml文件源码里面的default,和中央调度器定义映射方法镭同),用上一种方法是只加载和扩展名对应的请求。
	1)当项目中使用了 / , 它会替代tomcat中的default。
	  导致所有静态资源都给DispatcherServlet中央调度器处理,默认情况下DispatcherServlet没有处理静态资源。
	  但是没有控制器对象能处理静态资源的访问。所以静态资源(html, js, 图片, css)都是404,而动态资源some.do还是可以访问的,因为我们程序中有Mycontroller控制器对象,能处理some.do请求
	2)有两种处理方法(避免404):
		第一种处理静态资源的方法:
===========需要在springmvc配置文件中加入<mvc:default-servlet-handler>===============================
		原理:加入这个标签后,框架会创建控制器对象DefaultServletHttpRequestHandler(类似我们自己创建的MyController),DefaultServletHttpRequsetHandler这个对象可以把接收的请求转发给tomcat的default这个servlet。(即用了请求转发知识点,request.getRequestDispatcher("").forward可查看DefaultServletHttpRequsetHandler源码。
	3)但是 / 会把所有的请求都交给tomcat处理,因此<mvc:default-servlet-handler>和@RequestMapping注解有冲突,需要加入<mvc:annotation-driven/>注解驱动解决问题。
		=======第二种处理静态资源的方法:=============================================================
		<mvc:resources mapping="/images/**" location="/images/">
 		mvc:resources加入后框架会创建ResourceHttpRequestHandler这个处理器对象。
		mapping:访问静态资源的url地址,使用通配符**,(**不仅代表文件,也可以代表子目录,可用于使用一个配置语句,指定多种静态资源的访问)。
		location:访问静 态资源在你的项目中的目录位置。
		但是仍然要加上注解驱动<mvc:annotation-driven/>,不然动态资源无法访问
-->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

2. 控制器类(controller包下的MyController类)

需要在resources包下的springmvc.xml文件中声明组件扫描器。

@Controller
public class MyController {
    @RequestMapping("/some.do")
    public ModelAndView doSome(){
        //这里将service调用处理省略了

        ModelAndView mv = new ModelAndView();

        //相当与javaWeb基础中的request.serAttribute("","");
        //然后在jsp文件中getAttribute()获取
        mv.addObject("msg","欢迎使用");
        mv.addObject("fun","执行的是doSome方法");

        //指定视图,指定视图的完整路径。
        //框架对视图执行的forward操作,相当于javaWeb基础中的
        //request.getRequestDispatcher("/show.jsp").for(request,response)
        mv.setViewName("/show.jsp");
        return mv;
    }
}

3.视图解析器

resources包下的springmvc.xml文件(也有的用的DispatcherServlet.xml名称),InternalResourceViewResolver英文:内部资源视图解析器的意思。

<!--声明springmvc框架中的视图解析器,帮助开发人员设置视图文件的路径-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--  前缀:视图文件的路径  -->
    <property name="prefix" value="/WEB-INF/view"/>
    <!--  后缀:视图文件的扩展名  -->
    <property name="suffix" value=".jsp"/>
</bean>
//mv.setViewName("/WEB-INF/view/show.jsp");//可将此代码修改为下方代码
mv.setViewName("show");

4. 过滤器(在5监听器下面)

web.xml文件

<filter>
    <filter-name>characterEncodingFilter</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>
    <!--强制请求对象(HttpServletRequest)使用encoding编码的值-->
        <init-param>
        <param-name>forceRequestEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
    <!--强制应答对象(HttpServletResponse)使用encoding编码的值-->
        <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <!--
		/*:表示强制所有的请求先通过过滤器处理
	-->
	<filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

详情有单独的两篇文章介绍

  1. Get和Post请求方式
  2. 过滤器解决Post请求乱码

5.监听器(在1下面)

在使用监听器前需要加spring-web依赖

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.5.RELEASE</version>
</dependency>

web.xml加上下面配置

<!--
	监听器对象被创建后,会读取applicationContext.xml文件,或spring.xml文件(名字不同)
	为什么要读取:因为在监听器中要创建ApplicationContext对象,需要记载配置文件
-->
<context-param>
    	<!--contextConfigLocation:表示配置文件的路径-->
     <param-name>contextConfigLocation</param-name>
    	<!--自定义配置文件路径,原本默认是/WEB_INF/applicationContext.xml-->
      <param-value>classpath:conf/applicationContext.xml</param-value>
</context-param>
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  1. 需求:
    web项目中容器对象只需要创建一次, 把容器对象放入到全局作用域ServletContext中。

  2. 怎么实现:
    使用监听器 当全局作用域对象被创建时 创建容器 存入ServletContext

  3. 监听器作用:

​ 1)创建容器对象,执行 ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);

​ 2)把容器对象放入到ServletContext, ServletContext.setAttribute(key,ctx)

​ 3)监听器可以自己创建,也可以使用框架中提供好的ContextLoaderListener

  1. 配置监听器目的:是创建容器对象,创建了之后就能把spring.xml配置文件中所有的对象都创建好。用户发起请求就可以直接使用对象了。

  2. 如何调用?

    1)原本调用:即不使用监听器时

    String config = "spring.xml";
    ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
    

    2)使用监听器后:

    • 自己写的获取容器对象的方式

      //查看源代码分析
      String key = WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
      Object attr = getServletContext().getAttribute(key);
      if(attr != null){
      	ctx = (webApplicationContext)attr;	
      }
      
    • 框架提供的工具方法

      //使用框架中的方法获取容器对象
      ServletContxt sc = getServletContext();
      WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
      

    6. 注解驱动

    (与3.视图解析器同目录)

<!--
	1.响应ajax请求,放回json
	2.解决静态资源访问问题
-->
<mvc:annotation-driven/>

需要加约束,不加会报错annotation-driven" is not bound.

xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"

7.属性配置文件

  1. 与spring.xml文件同级
jdbc.url=jdbc:mysql://localhost:3306/springdb
jdbc.username=root
jdbc.password=A5413216
jdbc.maxActive=20
  1. 在spring.xml文件中,既然调用属性配置文件,就要声明文件的位置。
<context:property-placeholder location="classpath:conf/jdbc.properties"/>

四. bug:

  1. 错误描述:网页404,/show.jsp文件未找到

    原因:将show.jsp文件放入到了webapp包下的WEB-INF包中了。应该放入webapp包下就可以了,与index.jsp,WEB-INF包同级。将jsp文件放入到WEB-INF包中可以防止用户通过地址栏输入非法跳转下一个页面。在后面的讲解中就将show.jsp放入到该包中,但是doSome方法中的地址理应修改。

    WEB-INF:是Java的WEB应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。有时候,为了安全,可能需要把jsp文件放在WEB-INF目录下。

  2. 网页报错:

    org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [springmvc.xml]; nested exception is java.io.FileNotFoundException: class path resource [springmvc.xml] cannot be opened because it does not exist
    

    HTTP状态 500 - 内部服务器错误

    类型 异常报告

    消息 Servlet[springmvc]的Servlet.init()引发异常

    描述 服务器遇到一个意外的情况,阻止它完成请求。

    **原因:**在编译后target目录下的classes目录下没有resources资源包下的springmvc.xml文件,复制粘贴后便可以运行成功

    到底是为什么编译成这样不太清除

遗留问题:

  1. bug中的第二个问题,到底是为什么会变成那样。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值