流程分析
在我们做视图解析的时候,有不同的解析方式,比如有直接输入json数据、重定向、转发、输出文件流等多种方式。
通常采用哪种解析方式由执行方法的返回值决定,例如返回一个字符串,我们可以把返回的字符串当做响应的页面,
这时候可以采用转发的方式,如果返回的是一个JSONBEAN,这时候我们可以采用输出json字符串的方式解析。像这
一块的实现,我们可以采用适配器模式实现。
实现步骤大体如下
1、定义一个视图解析接口ViewHandler,提供2种解析方式,分别为json输出和forward
2、为接口实现每种解析方式。分别创建PrintViewHandler和ForwardViewHandler
3、创建一个视图渲染接口View,View中提供渲染方法render
4、创建View的渲染实现ViewAdapter,通过提供的相应结果,来创建对应的试图解析器,并调用解析方式
一些工具类就不贴出来了,但是我会标注用途,如果需要,请私信或者评论,我这把会把源码赠与.
初始化工作
继承Servlet类,重写init方法,目的是初始化
public class BaseInit extends HttpServlet {
// 请求路径和对应的方法
public static Map<String, Method> methods;
@Override
public void init(ServletConfig config) throws ServletException {
// 这个方法是用于解析requestMapping注解的,将关系存进去
try {
methods = ParseAnnotation.parseRequestMapping();
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建视图解析器接口
/**
* 视图解析器接口 提供字符串解析和转发的
*/
public interface ViewHandler {
default public void printString(HttpServletResponse response,Object result){}
default public void forward(HttpServletRequest request,HttpServletResponse response,Object result){}
}
解析字符串的类简简单单的实现一下
public class PrintStringViewHandler implements ViewHandler {
@Override
public void printString(HttpServletResponse response, Object result) {
// 设置格式为JSON
response.setContentType("application/json");
try {
PrintWriter writer = response.getWriter();
writer.write(JSONObject.toJSONString(result));
writer.close();
} catch (IOException e) {
}
}
}
转发的实现类简简单单转发一下
public class ForwardHandler implements ViewHandler {
@Override
public void forword(HttpServletRequest request, HttpServletResponse response, Object result) {
// 转发
try {
request.getRequestDispatcher(result.toString()).forward(request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
好了,解析完了之后我们渲染一下
视图渲染
先写一个视图接口
public interface View {
// 渲染
public void render(HttpServletRequest request, HttpServletResponse response,Object result);
}
简简单单实现一下
public class ViewAdapter implements View {
private ViewHandler viewHandler;
@Override
public void render(HttpServletRequest request, HttpServletResponse response, Object result) {
// 判断
if(result instanceof String){
// 转发
viewHandler = new ForwardHandler();
viewHandler.forword(request,response,result);
}else{
viewHandler = new PrintStringViewHandler();
viewHandler.printString(response,result);
}
}
}
对结果进行判断(处理),做出不同的决策.
请求的拦截
我们这里简简单单的对请求做一个拦截,需要service方法来拦截.
这里来插一嘴
uri 和url的区别
URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
这个是从网上搜罗过来的讲的似乎有点抽象,笔者这里举个例子帮助大家更好理解.
uri:相当于人唯一的标识身份证
url:相当于例如有个人叫虎弟,来自东百,那么url应该是 中国/东百/粪坑/虎弟/xxxxxxxx
这就是区别.可以理解为URL是URI的子集
public class DispacherServlet extends BaseInit {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取uri
String uri = req.getRequestURI();
Object result = invoke(uri);
if(result != null){
View view = new ViewAdapter();
view.render(req,resp,result);
}
}
private Object invoke(String uri) {
// 获得方法
Method method = methods.get(uri);
if(method != null){
Class<?> clazz = method.getDeclaringClass();
try {
method.invoke(clazz.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
这里就是大概全过程了.下次会写一下,工厂模式解析xml文件的内容.如果有纰漏或者有不明白或者想要源码,请评论或者私信.如果新手在学习过程中遇到问题,可以无偿解答,赠人玫瑰,手有余香.