微头条项目实战:新增RequestHeader注解

1、RequestHeader

java 复制代码
package com.csdn.mymvc.annotation;
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RequestHeader {
}

2、DispatcherServlet

java 复制代码
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);
            }
        }
    }
}
相关推荐
天远Date Lab2 分钟前
Java微服务实战:聚合型“全能小微企业报告”接口的调用与数据清洗
java·大数据·python·微服务
lizz316 分钟前
C++操作符重载深度解析
java·c++·算法
武子康7 分钟前
Java-205 RabbitMQ 工作模式实战:Work Queue 负载均衡 + fanout 发布订阅(手动ACK/QoS/临时队列)
java·性能优化·消息队列·系统架构·rabbitmq·java-rabbitmq·mq
CodeCraft Studio8 分钟前
Vaadin 25 正式发布:回归标准Java Web,让企业级开发更简单、更高效
java·开发语言·前端·vaadin·java web 框架·纯java前端框架·企业级java ui框架
Haoea!19 分钟前
JDK21新特性-序列集合
java
快乐非自愿27 分钟前
Java函数式接口——渐进式学习
java·开发语言·学习
wanghowie34 分钟前
01.01 Java基础篇|语言基础与开发环境速成
java·开发语言
白露与泡影36 分钟前
2026年Java面试题目收集整理归纳(持续更新)
java·开发语言·面试
百***787544 分钟前
【技术教程】3步极速接入GPT-5.1:零门槛体验多模态AI能力
android·java·人工智能·gpt·opencv
默 语1 小时前
IPIDEA 代理技术在海外品牌社媒数据采集中的实操落地(Instagram 营销分析案例版)
java·人工智能·ai·ai编程