1.写一个类继承serlve
1.1类中先获取请求的URI(请求地址)
就是找到那个请求中对应的方法.
/**
* 根据uri获取截取action
* @param requestURI
* @return
*/
private String getActionName(String requestURI) {
//1.获取"/"的最后索引,最后一个斜杠就是action
int index = requestURI.lastIndexOf("/");
return requestURI.substring(index+1);
}
1.2判断该类中有没有该方法
/**
* 找类中有没有包含actionName的方法
* @param actionName
* @return
*/
private Method findActionMethod(String actionName) {
//1.首先获取类中所有的方法名称
Method[] methods = this.getClass().getMethods();
//2.遍历,判断是否包含actionName
for (int i = 0; i < methods.length; i++) {
//3.判断类名是否包含actionName
if (methods[i].getName().equals(actionName)){
return methods[i];
}
}
return null;
}
1.3判断是否找到了类中对应的方法
//3.判断是否找到了actionName
if (actionMethod == null){
System.out.println("没有找到相对于的"+actionName);
return;
}
1.4获取处理方法的参数(传递过来的参数)
1.4.1先获取参数的长度,创建Object数组存放参数
1.4.2获取方法的形参,遍历参数数组
1.4.3遍历获取参数,获取形参的名字,利用Request根据形参的名字获取请求传递的参数
1.4.4把参数放入数组中,返回出去
1.4.5判断参数的类型(对象,还是参数)
对象
1.利用反射获取实例(newInstace)
2.Reques.getParameterMap():获取对象所有的参数,封装在Map集合里面,对象的属性就是Map的Key,不存在就为Null
3.讲Map中的Key赋值给数组里面(BeanUtils.populate(数组,参数集合)
4.返回
属性
1.判断参数的类型(getType())
2.强转.
3.放进数组里面返回
/**
* 获取方法中的参数.存放数组并返回
* @param actionMethod
* @param request
* @return
*/
private Object[] actionMethodParameter(Method actionMethod, HttpServletRequest request,HttpServletResponse response) {
//创建一个数组,放入参数.actionMethod.getParameterCount()==:参数的长度
Object[] object = new Object[actionMethod.getParameterCount()];
//1.获取方法的所有形参
Parameter[] parameters = actionMethod.getParameters();
//2.遍历参数数组
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
//2.1获取每个形参的名字
String name = parameter.getName();
Object value = null;
//2.2根据形参的名字从request中获取值
value = request.getParameter(name);
//2.3把获取的参数,放入数组里面
if (value == null || "".equals(value)){
//如果是一个对象,那么获取的value就是null,也可能是request或者
if (EmpCantons.TYPE_HTTPSERVLETREQUEST.equals(parameter.getType().getSimpleName())){
value = request;
}else if (EmpCantons.TYPE_HTTPSERVLETRESPONSE.equals(parameter.getType().getSimpleName())){
value = response;
}else {
try {
//利用反射获取参数的实例.此时参数是对象
Object o = parameter.getType().newInstance();
//获取请求中的所有参数,Map中的key就是对象的属性.前提是对象中必须要有此属性
Map<String, String[]> parameterMap = request.getParameterMap();
//讲map中的数据拷贝到对象o中,没有的就为null
BeanUtils.populate(o,parameterMap);
value = o;//然后讲对象传入数组里面
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}else {
//获取参数的类型,然后讲参数强转
Class<?> type = parameter.getType();
if (type.getSimpleName().equals("Integer")){
value = Integer.parseInt(value.toString());
}else if (type.getSimpleName().equals("Double")){
value = Double.parseDouble(value.toString());
}//还有许多...
}
object[i] = value;
}
return object;
}
1.5执行方法invoke
invoke(对象,方法参数)
//5.调用方法
try {
//获取方法的返回值,actionMethod是需要执行的方法,obj是哪个对象.argsArray是方法的参数,invoke方法的返回值
Object invoke = actionMethod.invoke(this, argsArray);
if (invoke!= null){
requestClient(invoke.toString(),request,response);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
1.6判断该方法的返回值
1.6.1先分割字符串,获取跳转的方式和跳转的路径
1.6.2判断跳转的方式,在根据跳转的方法跳转到执行的路径
private void requestClient(String resp, HttpServletRequest request, HttpServletResponse response) {
//1.按照冒号分割
String[] split = resp.split(":");
//2.获取跳转的方式
String type = split[0] ;
//3.获取跳转的页面的路径
String page = split[1];
//4.判断跳转的方式
if (EmpCantons.TYPE_FORWARD.equals(type)){
try {
//转发会参考当前路劲,需要加上"/",从web根目录开始
request.getRequestDispatcher("/"+page).forward(request,response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else if (EmpCantons.TYPE_REDIRECT.equals(type)){
try {//重定向加了/就是从端口号开始,所以需要加上当前路劲
response.sendRedirect(request.getContextPath()+"/"+page);
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结:本次也是学习,还有许多不足的地方,请各位大佬多多指教…
本文介绍了在学习JavaWeb时,如何通过自定义DispatcherServlet来实现动态请求映射。详细步骤包括:获取请求URI,检查类中是否存在对应方法,处理方法参数,通过反射执行方法,以及判断并处理方法返回值进行页面跳转。
303

被折叠的 条评论
为什么被折叠?



