如下的文档内容你能够移步到 [Rual(http://github.com/nullcodeexecutor/rural) 查看。java
这个框架的设计初衷是彻底无注解无配置,不事后来发现真正无注解无配置并不必定简洁,好比拦截器的使用如今只有靠代码来代替配置。这个小小框架的代码真的有点惨不忍睹。 你们有什么设计和代码上的建议请提出一块儿交流。git
<br/>github
####1 Getting Started #####1.1 Introduction Rural是一个基于spring的mvc框架,设计上相似spring mvc,相比于spring mvc,Rural使用更简便,无需配置和注解就能够实现URL到java方法的映射。 取名Rural(乡村风味的,田园的)寓意简洁。<br/> 目前Rural支持json,jsp,freemarker三种视图。 #####1.2 Hello World 首先在web.xml中配置,相似spring mvc,须要配置listener来启动spring context,配置servlet负责请求分发web
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>rural</servlet-name> <servlet-class>org.rural.context.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>rural</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
增长spring bean配置以下spring
<bean id="defaultRuralConfig" class="org.rural.config.DefaultRuralConfig"/>
而后编写controllerjson
@Controller public class HelloController { public String sayHello(Model model) { model.put("msg", "Hello World!"); return "json"; } }
访问url /contextPath/hello/sayHello
时,methodsayHello
将执行,容器返回以下json字符串mvc
{"msg":"Hello World!"}
####2 Config Rural配置极少,通常只须要配置默认的DefaultRuralConfig便可。若须要更改配置或须要定义拦截器则可自定义配置类,继承自DefaultRuralConfig便可。app
@Component public class RuralConfig extends DefaultRuralConfig { @Override public void setInterceptorConfig(InterceptorConfigHolder interceptorConfigHolder) { super.setInterceptorConfig(interceptorConfigHolder); //增长拦截器 interceptorConfigHolder.add("/user/*", UserInterceptor.class); } @Override public void setContextConfig(ContextConfigHolder contextConfigHolder) { super.setContextConfig(contextConfigHolder); //重写定义某些配置,这里重定义了模板类型为freemarker contextConfigHolder.add(TEMPLATE, "fm"); } }
DefaultRuralConfig 类中定义了全部Rural支持的配置。框架
@Override public void setContextConfig(ContextConfigHolder contextConfigHolder) { //请求响应编码类型 contextConfigHolder.add(CHARSET, "UTF-8"); //模板类型,目前只支持jsp和fm(freemarker) contextConfigHolder.add(TEMPLATE, "fm"); //页面文件所在位置 contextConfigHolder.add(PAGE_LOCATION, "/WEB-INF/page/"); //资源文件所在位置 contextConfigHolder.add(RESOURCES_LOCATION, "/resources"); //Controller所在包 contextConfigHolder.add(CONTROLLER_LOCATION, ""); }
####3 URL Mapping #####3.1 Default Rural自动创建URL到方法的映射。当有以下两个Controller类和方法URL映射以下<br/>jsp
org.coder.controller.HelloController public String sayHello(Model model) org.coder.controller.resc.ResouceController public String fineOne(Model model);
当没有配置CONTROLLER_LOCATION
时,默认全部以Controller为后缀的类都是Controller,url路径为类名截去后缀Controller
,再把首字母小写。<br/> 以上所示的两个方法分别对应URL /hello/sayHello
和/resource/findOne
。 #####3.2 自定义Controller包位置 当自定义Rural Config的CONTROLLER_LOCATION后,必须知足以该包名开头且以Controller为后缀的类才是Controller,且包名会与URL路径对应。 如类结构仍为3.1所示,设置
@Override public void setContextConfig(ContextConfigHolder contextConfigHolder) { super.setContextConfig(contextConfigHolder); contextConfigHolder.add(CONTROLLER_LOCATION, "org.coder.controller"); }
此时两个URL 为/hello/sayHello
和/resc/resource/findOne
。 ####4 Metadata Inject #####4.1 Is what metadata Metadata是指可以被Rural自动注入在URL对应的方法参数的数据类型,这包括请求类型和其它一些servlet和rural相关类型。<br/> 如访问urlxxx/findOne?name=myname&age=24
,以下的方法中的参数name,age,model都会被自动注入。
public String findOne(String name, int age, Model model, HttpServletRequest request){ System.out.println("user findOne ..."); model.put("name", name); model.put("age", age); return "forward:user"; }
#####4.2 全部能被注入的类型 可以被Rural注入的请求参数类型包括8种基本数据类及其包装器类型和String类型。 此外还有三个servlet相关类型,ServletContext,HttpServletRequest,HttpServletResponse,HttpSession。注入这四个类型是必须定义成这几个接口类型。 还有比较特殊的类型Model,该类其实是一个HashMap,用于持有用于页面渲染的数据类型。当模板类型是JSP时,model中的数据会自动转存到request中。 ####5 View Controller中的方法必须返回String,String的内容指明了该此请求使用何种视图。
下列情景Rural会返回/WEB-INF/page/user/one.ftl页面渲染的结果。
contextConfigHolder.add(TEMPLATE, "fm"); contextConfigHolder.add(PAGE_LOCATION, "/WEB-INF/page/");
public String user(Model model){ model.put("user", new User("lisi", 18)); return "forward:user/one"; }
####6 Interceptor Rural支持自定义拦截器,继承抽象类Interceptor
。不管before
仍是after
方法返回false
都会使请求链终止。
@Component public class UserInterceptor extends Interceptor{ @Override public boolean before(HttpServletRequest request, HttpServletResponse response) { System.out.println("user before"); return true; } @Override public boolean after(HttpServletRequest request, HttpServletResponse response) { System.out.println("user after"); return true; } }
Rural拦截器的配置须要在代码中完成。拦截器中URL配置使用的是org.springframework.util.AntPathMatcher
@Component public class MyConfig extends DefaultRuralConfig { @Override public void setInterceptorConfig(InterceptorConfigHolder interceptorConfigHolder) { super.setInterceptorConfig(interceptorConfigHolder); interceptorConfigHolder.add("/user/*", UserInterceptor.class); } @Override public void setContextConfig(ContextConfigHolder contextConfigHolder) { super.setContextConfig(contextConfigHolder); } }