public class V1HandlerAdapter {
public boolean supports(Object handler){ return (handler instanceof V1HandlerMapping);}
V1ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
V1HandlerMapping handlerMapping = (V1HandlerMapping)handler;
//把方法的形参列表和request的参数列表所在顺序进行一一对应
Map<String,Integer> paramIndexMapping = new HashMap<String, Integer>();
//提取方法中加了注解的参数
//把方法上的注解拿到,得到的是一个二维数组
//因为一个参数可以有多个注解,而一个方法又有多个参数
Annotation[] [] pa = handlerMapping.getMethod().getParameterAnnotations();
for (int i = 0; i < pa.length ; i ++) {
for(Annotation a : pa[i]){
if(a instanceof V1RequestParam){
String paramName = ((V1RequestParam) a).value();
if(!"".equals(paramName.trim())){
paramIndexMapping.put(paramName, i);
}
}
}
}
//提取方法中的request和response参数
Class<?> [] paramsTypes = handlerMapping.getMethod().getParameterTypes();
for (int i = 0; i < paramsTypes.length ; i ++) {
Class<?> type = paramsTypes[i];
if(type == HttpServletRequest.class ||
type == HttpServletResponse.class){
paramIndexMapping.put(type.getName(),i);
}
}
//获得方法的形参列表
Map<String,String[]> params = request.getParameterMap();
//实参列表
Object [] paramValues = new Object[paramsTypes.length];
for (Map.Entry<String, String[]> parm : params.entrySet()) {
String value = Arrays.toString(parm.getValue()).replaceAll("\\[|\\]","")
.replaceAll("\\s",",");
if(!paramIndexMapping.containsKey(parm.getKey())){continue;}
int index = paramIndexMapping.get(parm.getKey());
paramValues[index] = caseStringValue(value,paramsTypes[index]);
}
if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())) {
int reqIndex = paramIndexMapping.get(HttpServletRequest.class.getName());
paramValues[reqIndex] = request;
}
if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())) {
int respIndex = paramIndexMapping.get(HttpServletResponse.class.getName());
paramValues[respIndex] = response;
}
Object result = handlerMapping.getMethod().invoke(handlerMapping.getController(),paramValues);
if(result == null || result instanceof Void){ return null; }
boolean isModelAndView = handlerMapping.getMethod().getReturnType() == V1ModelAndView.class;
if(isModelAndView){
return (V1ModelAndView) result;
}
return null;
}
private Object caseStringValue(String value, Class<?> paramsType) {
if(String.class == paramsType){
return value;
}
//如果是int
if(Integer.class == paramsType){
return Integer.valueOf(value);
}
else if(Double.class == paramsType){
return Double.valueOf(value);
}else {
if(value != null){
return value;
}
return null;
}
//如果还有double或者其他类型,继续加if
//这时候,我们应该想到策略模式了
//在这里暂时不实现,希望小伙伴自己来实现
}
}