?
简介:轻量封装Spring MVC
? ? ? ? ?因为本人在国内最大的电子商务公司工作期间,深感一个好的Web框架可以大大提高工作效率,而一个不好的Web框架,又可以大大的降低开发效率。所以,在根据笔者在从事电子商务开发的这几年中,对各个应用场景而开发的一个轻量封装Spring MVC的一个Web框架。
? ? ? ? ?笔者工作的这几年之中,总结并开发了如下几个框架: summercool-web(Web框架,已经应用于某国内大型网络公司的等重要应用)、summercool-hsf(基于Netty实现的RPC框架,已经应用国内某移动互联网公司)、summercool-ddl(基于Mybaits的分表分库框架,已经应用国内某移动互联网公司);相继缓存方案、和消息系统解决方案也会慢慢开源。summercool框架做为笔者的第一个开源框架
?
?
框架地址:http://summercool.googlecode.com/svn/trunk/summercool-web?
应用地址:http://summercool.googlecode.com/svn/trunk/summercool-petstore?
工具地址:http://summercool.googlecode.com/svn/trunk/summercool-tools
说明:此框架要用到spring-tools文件夹中的security文件夹中的文件,使用此框架的人员请将security文件夹的内容替换到JDK中的security文件夹中
?
一、web.xml配置
?
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>summercool-petstore</display-name> <!-- Encoding Filter --> <filter> <filter-name>Set Character 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>Set Character Encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>summercool</filter-name> <filter-class>org.summercool.web.servlet.DispatcherFilter</filter-class> </filter> <filter-mapping> <filter-name>summercool</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.htm</welcome-file> </welcome-file-list> </web-app>
?说明:
? ? ? ? ? ?1.?Set Character Encoding:字符编码过滤器
? ? ? ? ? ?2.?summercool:summercool框架过滤器
? ? ? ? ? ?3. 只要配置上面两个filter即完成了应用框架的启动配置
?
二、summercool相关配置文件加载及说明
1. 笔者在设计框架的时候,想到了OSGI,但是一直也没有学习明白OSGI的好处或是说优势能给框架带来的什么提升。但是,笔者想实现一种不需要Spring配置文件的注入就可以动态扫描相关的配置文件,实现Spring相关功能类加载。
2. 因为上述的考虑,所以笔者用一种没有技术含又自认为比较方便的方式实现上述功能,如summercool框架会自动扫描:/summercool/spring/*.xml文件夹下面的所有的Spring配置文件。
说明:上图中的/summercool/spring文件夹下面的Spring配置文件全部都会自动加载,包括依赖的项目或是jar里包括的/summercool/spring的文夹下面的配置文件。
3. 在petstore应用里面,笔者一共预先建立了下面几个配置文件:
? ? 1) applicationContext.xml
? ? 2) cache-init-config.xml
? ? 3) cookie-configurer.xml
? ? 4) exception-configurer.xml
? ? 5) monitor-configurer.xml
? ? 6) petstore-configurer.xml
? ? 7) url-configurer.xml
? ? 说明:在上面几个配置文件中,要想要petstore应用跑里面,上面1) applicationContext.xml和6) petstore-configurer.xml这两个配置文件是不可缺少的。
? ? ? ? ? ? ? ?A. applicationContextml里面配置的是petstore页面模版信息和一些Spring MVC框架的配置信息。
? ? ? ? ? ? ? ?B. petstore-configurer.xml里面配置的是信息是summercool的一些请求映射信息等。是整个summercool框架的核心配置文件之一;下面会详细讲解。
?
三、核心配置文件讲解
1. applicationContext.xml配置文件说明
?
<?xml version="1.0" encoding="UTF-8" ?> <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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config/config.properties</value> </list> </property> </bean> <!-- 设置 MultipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <property name="maxUploadSize" value="20000000" /> <property name="maxInMemorySize" value="30720" /> </bean> <!-- 设置 HandlerExceptionResolver --> <bean id="handlerExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="defaultErrorView" value="/petstore/views/error" /> <property name="defaultStatusCode" value="500" /> </bean> <!-- #################################### --> <!-- 设置 ViewResolver --> <bean name="defaultResourceLoader" class="org.springframework.core.io.DefaultResourceLoader" /> <bean name="springTemplateLoader" class="org.summercool.view.freemarker.FreeMarkerTemplateLoader"> <constructor-arg index="0" ref="defaultResourceLoader" /> <constructor-arg index="1" value="${org.summercool.petstore.template.templateLoaderPath}" /> </bean> <bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean"> <property name="templateLoaderPath" value="${org.summercool.petstore.template.templateLoaderPath}" /> <property name="postTemplateLoaders"> <array> <ref bean="springTemplateLoader"></ref> </array> </property> <property name="freemarkerSettings"> <props> <prop key="default_encoding">UTF-8</prop> <prop key="number_format">#</prop> <prop key="template_update_delay">${org.summercool.petstore.template.update.delay}</prop> <prop key="classic_compatible">true</prop> <prop key="auto_import">/macro/macros.ftl as spring</prop> <prop key="url_escaping_charset">UTF-8</prop> </props> </property> </bean> <bean id="freemarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="configuration" ref="freemarkerConfiguration" /> </bean> <!-- Spring MVC页面层FreeMarker的处理类 --> <util:map id="uriModuleConstants"> </util:map> <bean id="freemarkerResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="prefix" value="" /> <property name="suffix" value=".ftl" /> <property name="contentType" value="text/html; charset=UTF-8" /> <property name="attributes" ref="uriModuleConstants" /> </bean> <!-- #################################### --> </beans>
说明:
? ? ? ? 1. propertyConfigurer:该配置是用来配置Spring注入的一些变量信息。目前里面只是有FreeMarker的模版路径和模版缓存时间。
? ? ? ? 2.?MultipartResolver:如果你的Spring MVC中需要使用到文件上传的功能,则需要配置这个类。默认Spring MVC是不支持文件上传的,只有配了这个类才会支持多文件上传;否则不起到作用。具体的用法,有时间笔者会给出例子,因为是标准的Spring MVC多文件上传,在这里不多作说明。
? ? ? ? 3. HandlerExceptionResolver:全局错误处理器;在Spring MVC在系统发生异常的情况,会交给这个统一错误处理类来处理。比如说,上面配置中“defaultErrorView”属性可以告诉如果系统发生异常,则要显示的默认处理页面(注:支持【 redirect: 】等这样的Spring MVC框架中View对象的语法)。
? ? ? ? ? ? 补充:笔者其实是比较喜欢这个设计的,但是在真正的使用的时候,发现有些需求的情况是无法解决的。比如说,UserException中有一个errorCode属性,不同的errorCode属性会有不同的错误异常类型;可以跟据不同的errorCode可以跳转到不同的业页等。再比如,HandlerExceptionResolver处理类无法拦截“页面层次的异常”。所以,笔者才设计出了ExceptionPipeline接口,该接口的具体使用,笔记会在summercool-petstore应用中给出示例说明。
? ? ? ? 4.?freemarkerConfiguration:设置的是Spring MVC中freemarker页面模版的信息。在这里作者做了一点更改,支持classpath:下面的freemarker模版的加载,别的没有做任何的变动。具体的freemarker模版设置网上有很多的资类可以参数,笔都在这里不多做介绍了。
? ? ? ? ? ? 补充:为什么要做一个freemarker的classpath下面的模版加载类呢,是因为有时候在不同的jar包或是项目中,支持把模版文件以工程模块划分,所以支持放在classpath来解决这个需求。
? ? ? ? ? ? ? ? ? ? ?笔者认为上面的这些配置信息已经足够,一般不需要更多的配置了。具本上面每个配置的含义,大家可以网上查查,笔者也会有时间会在summercool-petstore应用中补充进去的。
? ? ? ? 5.?uriModuleConstants:这个配置比较关键,是配置freemarker页面中的全局参数的一个map。比如说,我想让freemarker页面加入一个全局变量"AppName : Petstore",则可以配置在此map中。使用的时候只要在freemarker的任何页面中使用${AppName}即可显示。同理,如果想在freemarker中加入全局的内置函数,当然也是通过此方法实现。
? ? ? ? 6.?freemarkerResolver:Spring MVC中真正使用的freemarker页面处理类,具体的实现和使用其实全部都是通过此类完成,具体该类的细节笔者在此不做细的讲解。
?
2. petstore-module.xml配置文件说明
?
<?xml version="1.0" encoding="UTF-8" ?> <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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="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/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean name="petstore" class="org.summercool.web.module.WebModuleConfigurer"> <property name="moduleName" value="petstore" /> <property name="uriExtension" value=".htm" /> <property name="moduleBasePackage" value="org.summercool.platform.web.module" /> <property name="context" value="/" /> <property name="contextPackage" value="/petstore/" /> </bean> <bean class="org.summercool.web.module.WebModuleUriExtensionConfigurer"> <property name="uriExtensions"> <util:list> <value>.htm</value> </util:list> </property> </bean> <!-- <import resource="classpath*:spring/petstore-service.xml"/> --> </beans>
?
说明:
? ? ? ? 1. 该类是笔者整个summercool框架最核心的配置了。
? ? ? ? 2.?org.summercool.web.module.WebModuleConfigurer:summercool框架会自动加载此类并且分析该类加载的一些配置信息。
? ? ? ? ? ? 在此应用中,有如下几个信息是非常重要的:
? ? ? ? ? ? 1)?moduleName:设置当前应用模块的名称(没有关键作用,其实框架也用不到,只是标识一下而已)
? ? ? ? ? ? 2)?moduleBasePackage:该模块包的根路径,主要是扫描Spring MVC的Controller和Widget类,这两个类的具体使用,笔者会在下一篇中做详细的讲解,这里只介绍一下基本规则。
? ? ? ? ? ? 3)?uriExtension: summercool框架扫描到该模块的Controller之后,生成的UrlMapping时的映射地址使用的扩展名是什么。比如说:/IndexController.java --> /index.htm 或 /user/ModifyUserController.java --> /user/modify_user.htm 这样的url对应关系。【驼峰命名法的类,对应使用下划线的URL方式】
? ? ? ? ? ? 4)?context:对应该模块的上下文。比如:context = "/" --> /index.htm 或 context = "petstore" --> /petstore/index.htm
? ? ? ? ? ? 5)?contextPackage:扫描该模块对应的模块目录。
? ? ? ? ? ? ? ? moduleBasePackage + contextPackage = 完整的该应用模块的招扫描路径
? ? ? ? ? ? ? ? 扫描该完整包路径下面的:controllers和widgets文件夹
? ? ? ? ? ? ? ? controllers文件夹的扫描规则是:/controllers/IndexController.java --> /context/index.htm
? ? ? ? ? ? ? ? 如果是按照上面的这个配置,则真实的规则是:/controllers/IndexController.java --> /index.htm (因为context = "/")
? ? ? ? ? ? 6) 模块配置类可以允许配置多个,也就是说可以配置多个应和模块,只要context不冲突即可。
? ? ? ? 3.?org.summercool.web.module.WebModuleUriExtensionConfigurer:summercool应用只允许有一个该配置类。该配置类主要是配置哪些过来的后缀名的url请求会允许交给summercool应用处理。
?
重要:到目前为止,所有的配置即已经完成了,可以运行应用。
? ? ? ? ?下一篇,笔者会就如何使用框架进行Controller及Widget开发展开讨论。
? ? ? ? ?再下一篇,笔者会就如何使用Pipeline开发展开讨论。
?
?
?
?
?
?