学写一个 Java Web MVC 框架
Posted sp42a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学写一个 Java Web MVC 框架相关的知识,希望对你有一定的参考价值。
获取请求参数的处理
对控制器的方法进行分析,看需要哪些参数,将得到的参数签名和请求过来的参数相匹配,再传入到控制器方法中去执行,这就是RequestParam
类的任务(取得控制器方法执行时候所需要的参数)。如下例子所示,我们看看典型的一个控制器方法,可能出现的参数类型。
@Path("/foo")
public class c1 implements IController {
@GET
public String get(Map<String, Object> params, HttpServletRequest r, HttpServletResponse res) {
return "get";
}
@POST
public String get2(ModelAndView mv, News news) {
return "get";
}
@Path("/bar")
@GET
public String getInfo2(@NotNull @QueryParam("name") String name, @QueryParam("sex") String sex) {
return "getInfo2";
}
@Path("/bar")
@POST
public String getInfo3(@QueryParam("sex") String sex) {
return "getInfo2";
}
@Path("/{id}")
@PUT
public String getInfo4(@PathParam("id") String id) {
return "getInfo2";
}
}
粗略统计要处理的类型有以下这些:必备的request/response;请求参数QueryParam/FormParam/PathParam/HeadParam
包括HEAD
里面的字段;请求参数转换为Java类型的int/long/boolean/String
;实体类型Map/Bean。还有处理是否非空、默认值等的注解。最终传入控制器方法的参数,影响的因素在于注解如何以及参数类型如何,如插图所示就是转换的方法RequestParam.getArgs()
。
转换过程有以下若干注意的点。
method.getParameterAnnotations()
返回方法参数的所有注解内容。即使参数没有任何注解也会返回一个空数组。- Servlet对HTTP PUT方法没有直接支持,这里的需求是返回类似POST的参数,也就是获取HTTP BODY里面的参数。遗憾的是Servlet没有支持,故在MvcRequest中封装了一个
getPutRequestData()
方法,返回一个Map。 - 转换为Map的参数符合
<String, Object>
类型,Object中的值都已经尽量转换为Java类型,例如字符串"1"变为整型1,字符串"true"变为布尔型true
…… - 获取URL上面的值(即
@PathParam
)时使用了正则匹配。 - 涉及较多注解的操作,不过难度不大,都是一对一的映射操作。
最终转换完毕,返回一列表ArrayList<Object> args
。此时此刻,目标的控制器具备了控制器实例、要执行的方法及其参数列表三者条件之后,它才能真正执行起来,执行后返回什么结果,怎么返回——我们下一小节继续看。
处理返回结果
终于到MVC的最后一步了!MvcOutput代表了控制器对用户请求进行处理后得到的内容,它可以解析一个字符串表示要跳转的视图或重定向到的资源的URL,也可以解析数据对象转换为JSON格式的字符串。支持的功能整理如下:html/JSP、JSON/JSONP/XML、Bean/Map自动转换为JSON输出。根据不同类型的输出采取相应的ContentType
输出。
MvcOutput依然采用装饰模式扩展自HttpServletResponseWrapper
,因为继承的关系拥有HttpServletResponse
一切的API。其次通过若干getter/setter施加于MvcOutput身上用于各状态的设定。其中private String output
字段是最终输出的字符串,可以是HMTL或其他内容。
核心方法是resultHandler()
,他根据控制器方法执行后返回的结果Object result
进行判断,采取相应的处理手段最终输出。输出的方法就是go()
。
以上是关于学写一个 Java Web MVC 框架的主要内容,如果未能解决你的问题,请参考以下文章