简洁的MVC框架Rural

如下的文档内容你能够移步到 [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的内容指明了该此请求使用何种视图。

  • json    json视图
  • forward:xxx/xx    经过forward形式跳转到页面,目前页面支持freemarker(fm)和jsp
  • redirect:xxx    经过redirect跳转到另外一个请求

    下列情景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);
    }
}
相关文章
相关标签/搜索