spring的一个小例子(二)--解析前面的小例子
接上篇:http://www.cnblogs.com/xuejupo/p/5236448.html
首先应该明白,一个web项目,web.xml是入口。
然后下面来分析上篇博客中出现的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 区分项目名称,防止默认重名 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>maven.cainiao.root</param-value>
</context-param>
<!-- Spring的log4j监听器 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 字符集 过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring view分发器 -->
<servlet>
<servlet-name>dispatcher_cainiao</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher_cainiao.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher_cainiao</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
首先是context-param参数,说context-param之前,应该有个概念:
web.xml的加载过程是context-param -> listener -> fileter -> servlet。
context-param属性在xml文件里是最先被加载的,但是只有他是然并卵的,他必须配合别的java类一起使用。context-param差不多就相当于一个web项目的内置map,key和value都是String,context-param的加载只是为这个map赋值,相当于配置参 数,让之后的监听或者过滤器等能够使用context-param中配置好的参数。
举个例子,我的web服务器是jboss,在context-param中配置参数
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>maven.cainiao.root</param-value>
</context-param>
后,jboss在加载这个项目的时候这个项目的别名就是maven.cainiao.root。这时候,如果在jboss中有别的项目也叫这个名字,那么jboss就会报错。
再比如说,如果要设定日志监听,就要在context-param中配置log4jConfigLocation参数,log监听器Log4jConfigListener会在加载的时候自动监听log4jConfigLocation参数对应的值下的文件;再比如,ContextLoaderListener监听器负责将contextConfigLocation参数路径下的xml文件加载。
当然,也可以自己做监听或者过滤器,然后在web.xml中通过context-param配置过滤的参数(通过ServletConfig.getInitParameter(key))。
然后就是org.springframework.web.util.Log4jConfigListener,这是一个spring的log4j监听器。实际上我们不实用这个监听也是可以的,但是使用它有几个好处:
首先如果不用他,那么log的配置文件log4j.properties必须写在classpath下,而用它的话,你就可以很方便得管理log4j.properties的位置了。
其次,这个监听中有个方法会每隔60秒扫描log4j配置文件,这样修改log4j配置文件就可以不用重启服务了。
再然后,字符过滤器CharacterEncodingFilter,可以看到filter-mapping中的url-pattern是/*,他负责将/*(也就是全部路径)下的所有请求,强制转换为UTF-8编码的形式,这样如果在编写页面的时候也用utf-8
编码,就可以防止乱码的产生了。
最后就是跟我们打交道最多的servlet了。首先看servlet-mapping,这里有个url-pattern,这里匹配url里输入的,比如说上面的web.xml中这里是/,那么,所有的http://localhost:8080/test/*的url都会被这个名字叫做dispatcher_cainiao的servlet解析。servlet-mapping下的servlet-name对应servlet下的servlet-name,根据name找到具体的servlet(servlet-mapping是servlet的入口,感觉更像是接口,负责servlet的入口url和对应具体的servlet实现类);而这个servlet-class,就是具体的servlet实现类了。当然,我们可以写自己的实现类,这样url就会请求到我们自己的servlet里(现在已经很少有这种写法了),还可以交给spring托管,比如实现类写org.springframework.web.servlet.DispatcherServlet,这是spring框架中的一个流程控制器,负责分发url。init-param表示将初始化他的配置参数,如上面的配置中,这个分发器使用的配置文件路径为:/WEB-INF/dispatcher_cainiao.xml,load-on-startup表示他在web容易启动的时候会自加载(这个很重要,不加这个你的url就找不到可以分发的servlet了)。
再来看分发器使用的xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<mvc:annotation-driven />
<!-- <mvc:default-servlet-handler/> -->
<context:component-scan base-package="controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
</bean>
</beans>
首先,mvc:annotation-driven是一种简写模式,表示自动加载DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。context:component-scan是spring中的自动扫描机制,负责扫描包以下所有类中包含的所有spring注解。
然后,就是注册一个bean了:InternalResourceViewResolver,视图解析类,就是将servlet中的返回解析到prefix对应参数文件夹下的suffix对应的后缀文件。
他需要配合控制类使用:
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.cainiaojava.beans.User;
/**
* DispatcherController:
* @author xuejupo jpxue@travelsky.com
*
* create in 2016-3-1 下午3:35:13
*
*/
@Controller
@RequestMapping("demo")
public class DispatcherController {
@RequestMapping(method=RequestMethod.GET)
public String printWelcome(ModelMap model) {
User user = new User();
user.setInfo("哈哈,我是唯一的用户!");
user.setUserName("我是老大!");
user.setPasswd("不告诉你!");
model.addAttribute("str0121", "我去,成功了呀!!!");
model.addAttribute("info","当前用户信息为:");
model.addAttribute("user", user);
System.out.println("index.jsp");
return "index";
}
}
@Controller表示这是一个控制器,@RequestMapping("demo")表示他接收后缀为demo的url(比如http://localhost:8080/test/demo),@RequestMapping(method=RequestMethod.GET)表示请求方式是get的话进这个方法,ModelMap是spring内置的ui控制类,可以将值传到前端。 return "index",和前边说的suffix参数的值,合组成index.jsp,所以这个servlet会将请求返回到页面index.jsp中。
总结一下:
首先加载web.xml,web.xml中首先加载context-param,他们没什么实际意义,只是一个上下文。然后加载监听,上面的web.xml配置了log监听器,所以加载Log4jConfigListener文件(配置log监听器,应该要在context-param中配置log4jConfigLocation参数,我是犯懒,还没配日志。。),然后,加载字符过滤器CharacterEncodingFilter,再然后自上而下加载servlet(本文只有一个servlet,不存在先后顺序问题),加载DispatcherServlet分发器,这时候就要加载分发器的配置文件dispatcher_cainiao.xml了。在dispatcher_cainiao.xml中,因为 写了mvc:annotation-driven,所以加载DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter两个bean,然后扫描包controller,处理包controller下的所有文件包含的注解,然后配置视图解析类InternalResourceViewResolver,再然后web项目启动完毕。
当我们请求http://localhost:8080/test/demo的时候,首先根据http://localhost:8080/test找到这个项目,然后根据/demo,在servlet-mapping中的url-pattern中查找对应的项,找到一个dispatcher_cainiao,然后根据注解@RequestMapping("demo")找到文件DispatcherController,然后进入相应的方法处理,最后返回的时候根据return值index和配置文件中的InternalResourceViewResolver视图管理,找到jsp文件/views/index.jsp,最后就是渲染jsp文件了。
ps:
首先,web项目的唯一入口是web.xml(不知道是不是有其他入口,我是菜鸟,如果有其他入口希望大神留言指正),其他的xml文件都是在web.xml文件中注册过的,或者是在servlet或者监听器中被加载的,而监听也是在web.xml中注册的,所以所有的配置文件,都能从web.xml通过一定的路径走到。学spring框架一定要知道他的大概流程是什么。所以初学spring,建议找一张白纸,好好画一画他的流程走向是什么,很有帮助的。
欢迎转载,但请标明出处:http://www.cnblogs.com/xuejupo/p/5252009.html, 也欢迎跟我讨论。
spring的一个小例子(二)--解析前面的小例子的更多相关文章
- 微信小程序参数二维码6问6答
微信小程序参数二维码[基础知识篇],从6个常见问题了解小程序参数二维码的入门知识. 1.什么是小程序参数码? 微信小程序参数二维码:针对小程序特定页面,设定相应参数值,用户扫描后进入相应的页面. 2. ...
- Java 获取微信小程序二维码(可以指定小程序页面 与 动态参数)
一.准备工作 微信公众平台接口调试工具 小程序的唯一标识(appid) 小程序的密钥(secret) 二.获取access_token 打开微信公众平台接口调试工具,在参数列表中输入小程序的appid ...
- 用GAN生成二维样本的小例子
同步自我的知乎专栏:https://zhuanlan.zhihu.com/p/27343585 本文完整代码地址:Generative Adversarial Networks (GANs) with ...
- C# Newtonsoft.Json解析数组的小例子[转]
https://blog.csdn.net/Sayesan/article/details/79756738 C# Newtonsoft.Json解析数组的小例子 http://www.cnblog ...
- 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
原地址:http://www.cnblogs.com/xuling/archive/2013/03/04/2943154.html 最近开始研究U3D,它的强大就不多说了, 今天研究了研究射线相关东西 ...
- 一个java解析xml的简单例子
java解析xml,主要是通过Dom4j实现的,很多场合都会用到此功能,需要解析XML文件. 下面是一个简单的解析XML文件的例子: import java.util.Iterator; import ...
- Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- 5.2 Spring5源码--Spring AOP源码分析二
目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...
- Spring是一个分层的Java
Spring简介 Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架.Spring核心是IOC和AOP. Spring优点 -方便解耦,简化开发,通过Spring提供的IoC容器, ...
- 2015年12月10日 spring初级知识讲解(二)最小化Spring XML配置 注解
序,随着Spring容器管理Bean数量增加,XML文件会越来越大,而且纯手工配置XML很繁琐,Spring和JAVA都提供了一些注解方式用以简化XML配置. 目录 一.自动装配(autowiring ...
随机推荐
- Chrome添加Axure RP插件
之前一直用 Firefox 浏览器浏览原型文件,一直用不惯,而且用 Firefox 的唯一目的就是看原型.其他都是用 Chrome 浏览器,来回切换,各种麻烦,然后下定决心解决 Chrome 浏览器无 ...
- 基于MPI的大规模矩阵乘法问题
转载请注明出处. /* Function:C++实现并行矩阵乘法; Time: 19/03/25; Writer:ZhiHong Cc; */ 运行方法:切到工程文件x64\Debug文件下,打开命令 ...
- 一个linux 驱动升级的小问题记录
重复踩了两次坑,所以简单记录下. 内核 3.10. 在修改了驱动的gro实现之后,进行驱动版本的升级,make && make install 之后,发现tg3的驱动,没有生效. 相同 ...
- wdcp lanmp 安装+搭建网站+安全狗安装 详细实用
先说一下WDCP,其实就是一个集成环境,优点是有后台可视化面板操作,不像一般的linux似的 都要用代码命令! Linux 的PHP 环境一般就是两个搭配 [mysql+Apache+PHP]和[My ...
- SSRS表达式里引用.net dll
在SSRS的表达式里使用了一个.NET的DLL,用来生成条码图片,发布以后用不了. 需要修改一个SSRS的权限配置项,确保Report_Expressions_Default_Permissions的 ...
- Day02 - Ruby比一比:Module模块与Class类别
前情提要 在第一天里,我很激昂地用Ruby的类别.物件.方法,写了宣言! class TingIsIronman def initialize @message =“I'm going to writ ...
- win7安装oracle 10g问题总结。
1.安装oracle10g的时候,出现此问题,如图: 右键安装程序(setup.exe) -> 属性 -> 兼容性 -> 以兼容模式运行这个程序 windows xp( servi ...
- c#Socket Tcp服务端编程
创建一个socket服务类,绑定监听端口, 然后创建一个线程listen连接的客户端, 把监听到的客户端加入dictionary里面,以便于管理, 同时创建receive线程,循环接收数据加入list ...
- ucos中的中断管理
一.中断的概念 中断是一种硬件机制,用于处理异步事件.中断的实时性比轮询要好,通过中断,微控制器可以在异常发生的时候立刻进行处理,而不需要不断轮询事件是否发生. CM3支持中断嵌套,使得高优先级异常可 ...
- 解决cpplint在Python 3下没有任何输出的问题
修改cpplint.py:1. main()中注释掉 # sys.stderr = codecs.StreamReaderWriter(sys.stderr, # codecs.getreader ...