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

xiaoxiao2026-08-07  13

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:@WebHandlerpublic 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) 但不推荐这样做。
转载请注明原文地址: https://www.6miu.com/read-5050828.html

最新回复(0)