一个简易的基于annotation的web MVC框架的实现

1、导入jar包
-- webmvc.jar
-- asm.jar

2、配置核心servlet

<servlet>
<servlet-name>WebServlet</servlet-name>
<servlet-class>
com.cwq.webmvc.core.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>handler-scan</param-name>
<param-value>com.xyz,com.abc</param-value> <!-- 配置包扫描列表,多个包用逗号隔开 -->
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>WebServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>


3、handler的定义
handler可以是一个普通的POJO,通过定义一系列的注解使其具备某些功能。

Context Path: /web
Servlet Mapping: *.do


示例1:

@RequestMapping("/Order/.*")
public class OrderHandler {

@RequestMapping(param = "load")
@ForwardUrl("/showOrder.ftl")
public void method1(int uid) // RequestURL: /web/Order/m1.do?uid=2&action=load
{
// do something...
}

@RequestMapping(param = "commond=method2")
@ForwardUrl("/showOrder.ftl")
public void method2(String name) // RequestURL: /web/Order/m1.do?name=张三&commond=method2
{
// do something...
}
}


示例2:

@RequestMapping("/User/.*")
@ForwardUrl("/showUser.ftl")
public class UserHandler {

public void save(User user) // RequestURL: /web/User/save.do?id=2&name=张三
{
// do something...
}

public void load(int id) // RequestURL: /web/User/load/2.do
{
// do something...
}
}


示例3:

@WebHandler
public class ProductHandler {

@RequestMapping("/Product/save")
@ForwardUrl("/showProduct.ftl")
public void save(Product product) // RequestURL: /web/Product/save.do?pid=2&pname=产品1
{
// do something...
}

@RequestMapping("/Product/load")
@ForwardUrl("/showProduct.ftl")
public void load(int pid) // RequestURL: /web/Product/load.do?pid=2
{
// do something...
}
}



[color=red]注解使用详细说明:[/color]
* @RequestMapping:定义在方法级别或类级别
* value: 定义要绑定到该类或方法的url,该url不需要加上ContextPath和ServletMapping。
* param: 定义形式key=value,只有request中有指定的值才满足匹配,如果未指定key,则默认为action,如 param = "save" 等价于 param = "action=save",类似struts

中的DispatchAction。
* method: 定义请求类型的绑定,如 method=RequestMethod.GET,则限定为只有GET请求方式才匹配。
* @ForwardUrl:定义在方法级别或类级别
* value: 定义需跳转的url
* @HandlerInitialize:标识注解,定义在方法级别,标识该方法为handler的初始化方法,在handler中每次请求处理之前都会先执行该方法。
* @HandlerDispose:标识注解,定义在方法级别,在handler中每次请求处理之后都会执行该方法。
* @MethodMapping:定义在方法级别,用于改变方法的绑定名字
* value:默认是以方法名匹配,如 @MethodMapping("newMethod") 将使用newMethod去匹配,而非方法名
* @ModelAttribute:定义在参数级别,定义该参数的值将从ModelMap中获取
* value:定义要获取值的key,如果ModelMap没有指定key对应的值,将抛出异常
* @ParameterConverter:标识注解,定义在方法级别,定义该方法为
* @RequestParam:定义在参数级别,改变参数的绑定名字,
* value:默认是以参数名绑定,如 @RequestParam("newParam") 将使用newParam去匹配,而非参数名
* @SessionAttributes:定义在类级别,指定ModelMap中的哪些值存储在session中
* value:定义定式{"key1","key2"...}
* @WebHandler:标识注解,定义在类级别,标识该类为request handler
* @ReturnKey:定义在方法级别,默认情况下,handler请求处理方法的返回值以'data'为key存储在request中,该注解用于自定义key值
* value:指定返回值新的key值

注意事项:
* 1、尽量不要在一个handler中同时使用基于annotation和REST两种风格的映射,最佳实践是在类级别统一使用@RequestMapping进行url映射,然后在方法级别通过param属性进行进一步分流。

* 2、尽量将绑定的url差异化定义的大一些,避免url出现包含关系,目前出现包含关系的处理方式是:在匹配的前提下,URL的length最大,即为最匹配的。

* 3、对于@RequestMapping的定义,如果出现类级别和类级别、类级别和方法级别、方法级别和方法级别的冲突,均会在servlet初始化时抛出异常。
* 冲突实例:
* 方法级:A、@RequestMapping(param = "method2")
* 方法级:B、@RequestMapping(param = "action=method2")

* 不冲突实例:
* 类级:A、@RequestMapping("/order/Aorder", method = RequestMethod.GET)
* 类级:A、@RequestMapping("/order/Aorder")

* 类级:A、@RequestMapping("/order/Border")
* 方法级:A、@RequestMapping("/order/Border", method = RequestMethod.POST)
但不推荐这样做。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值