1、RequestHeader
package com.csdn.mymvc.annotation;
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RequestHeader {
}
2、DispatcherServlet
package com.csdn.mymvc.core;
import com.csdn.mymvc.annotation.RequestBody;
import com.csdn.mymvc.annotation.RequestHeader;
import com.csdn.mymvc.util.RequestUtil;
import com.csdn.mymvc.util.ResponseUtil;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import com.csdn.headline.common.Result;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Map;
@WebServlet("/*")
public class DispatcherServlet extends HttpServlet {
private final String BEAN_FACTORY = "beanFactory" ;
private final String CONTROLLER_BEAN_MAP = "controllerBeanMap" ;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String[] staticResourceSuffixes={".html",".jsp",".jpg",".png",".gif",".css",".js",".ico"};
//index.html
String uri = request.getRequestURI();
if(Arrays.stream(staticResourceSuffixes).anyMatch(uri::endsWith)){
RequestDispatcher defaultDispatcher = request.getServletContext().getNamedDispatcher("default");
defaultDispatcher.forward(request,response);
}else{
// uri: /fruit/index
String[] arr = uri.split("/") ;
if(arr==null || arr.length!=3){
throw new RuntimeException(uri+"非法!");
}
// [, fruit, index]
String requestMapping = "/"+arr[1] ; // /fruit
String methodMapping = "/"+arr[2]; // /index
ServletContext application = getServletContext();
ControllerDefinition controllerDefinition = ((Map<String,ControllerDefinition>)application.getAttribute(CONTROLLER_BEAN_MAP)).get(requestMapping);
if(controllerDefinition==null){
throw new RuntimeException(requestMapping+"对应的controller组件不存在!");
}
//获取请求方式,例如:get或者post
String requestMethodStr = request.getMethod().toLowerCase();
//get_/index
Method method = controllerDefinition.getMethodMappingMap().get(requestMethodStr+"_"+methodMapping) ;
Object controllerBean = controllerDefinition.getControllerBean();
try {
//第1步:参数处理
//获取method方法上的参数
Parameter[] parameters = method.getParameters();
Object[] parameterValues = new Object[parameters.length];
for(int i = 0 ; i< parameters.length;i++){
Parameter parameter = parameters[i];
//获取参数名称
//JDK8之前,通过反射获取到参数对象(Parameter对象)
//然后通过parameter.getName()方法是得不到形参的名称的,返回的是arg0,arg1,arg2....
//JDK8开始,反射技术得到的Class中可以包含方法形参的名称,不过需要做一个额外的设置:java compiler 中添加一个参数:-parameters
String paramName = parameter.getName();
Object parameterValue = null ;
//获取当前这个参数上的所有注解
Annotation[] annotations = parameter.getDeclaredAnnotations();
if (Arrays.stream(annotations).anyMatch(annotation -> annotation instanceof RequestBody)) {
parameterValue = RequestUtil.readObject(request,parameter.getType());
} else if (Arrays.stream(annotations).anyMatch(annotation -> annotation instanceof RequestHeader)) {
parameterValue = request.getHeader(paramName);
} else{
String paramValueStr = request.getParameter(paramName);
if(paramValueStr!=null){
//获取参数的类型,例如: java.lang.Integer,java.lang.String
String parameterTypeName = parameter.getType().getName();
parameterValue = switch (parameterTypeName){
case "java.lang.String"->paramValueStr;
case "java.lang.Integer"->Integer.parseInt(paramValueStr);
default -> null;
};
}
}
parameterValues[i]=parameterValue;
}
//第2步:方法调用
//调用controllerBean对象中的method方法
method.setAccessible(true);
//第3步:结果集处理
Object returnObj = method.invoke(controllerBean,parameterValues);
if(returnObj!=null && returnObj instanceof Result){
Result result = (Result) returnObj ;
ResponseUtil.print(response,result);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}