项目实战:中央控制器实现(4)-实现RequestBody注解的功能-获取请求体参数

1、DispatcherServlet

java 复制代码
package com.csdn.mymvc.core;
import com.csdn.fruit.dto.Result;
import com.csdn.fruit.util.RequestUtil;
import com.csdn.fruit.util.ResponseUtil;
import com.csdn.mymvc.annotation.RequestBody;
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 org.junit.Test;
import java.io.IOException;
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";

    @Test
    public void uri() {
        String uri = "/fruit/index";
        String[] arr = uri.split("/");
        System.out.println(Arrays.toString(arr));//[, fruit, index]
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String[] staticResourceSuffixes = {".html", ".jsp", ".jpg", ".png", ".gif", ".css", ".js", ".ico"};
        String uri = req.getRequestURI();
        if (Arrays.stream(staticResourceSuffixes).anyMatch(uri::endsWith)) {
            RequestDispatcher defaultDispatcher = req.getServletContext().getNamedDispatcher("default");
            defaultDispatcher.forward(req, resp);
        } else {
            String[] arr = uri.split("/");
            if (arr == null || arr.length != 3) {
                throw new RuntimeException(uri + "非法!");
            }
            //[, fruit, index]
            String requestMapping = "/" + arr[1];
            String methodMapping = "/" + arr[2];

            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 = req.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];

                    RequestBody requestBodyAnnotation = parameter.getDeclaredAnnotation(RequestBody.class);
                    Object parameterValue = null;
                    if (requestBodyAnnotation != null) {
                        parameterValue = RequestUtil.readObject(req, parameter.getType());
                    } else {
                        //获取参数名称
                        //JDK8之前,通过反射获取到参数对象(Parameter对象)
                        //然后通过parameter.getName()方法是得不到形参的名称的,返回的是arg0,arg1,arg2....
                        //JDK8开始,反射技术得到的Class中可以包含方法形参的名称,不过需要做一个额外的设置:
                        //java compiler中添加一个参数:-parameters
                        String paramName = parameter.getName();
                        String paramValueStr = req.getParameter(paramName);
                        if (paramValueStr != null) {
                            //获取参数的类型
                            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);
                Object returnObj = method.invoke(controllerBean, parameterValues);
                if (returnObj != null && returnObj instanceof Result) {
                    Result result= (Result) returnObj;
                    ResponseUtil.print(resp,result);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }

        }
    }
}

2、FruitController

java 复制代码
package com.csdn.fruit.controller;
import com.csdn.fruit.dto.PageInfo;
import com.csdn.fruit.dto.PageQueryParam;
import com.csdn.fruit.dto.Result;
import com.csdn.fruit.pojo.Fruit;
import com.csdn.fruit.service.FruitService;
import com.csdn.mymvc.annotation.*;
@Controller
@RequestMapping("/fruit")
public class FruitController {
    @Autowire
    private FruitService fruitService;

    @GetMapping("/index")
    public Result index(Integer pageNo,String keyword) {
        if (pageNo == null) {
            pageNo = 1;
        }
        if (keyword == null) {
            keyword = "";
        }
        PageQueryParam pageQueryParam = new PageQueryParam(pageNo, 5, keyword);
        PageInfo<Fruit> pageInfo = fruitService.getFruitPageInfo(pageQueryParam);

       return Result.OK(pageInfo);

    }

    @PostMapping("/add")
    public Result add(@RequestBody Fruit fruit)  {
        fruitService.addFruit(fruit);
        return Result.OK();
    }

    @GetMapping("/del")
    public Result del(Integer fid){
        fruitService.delFruit(fid);
        return Result.OK();
    }

    @GetMapping("/edit")
    public Result edit(Integer fid){
        Fruit fruit = fruitService.getFruitById(fid);
        return Result.OK(fruit);
    }

    @GetMapping("/getFname")
    public Result getFname(String fname){ //fname是请求参数
        Fruit fruit = fruitService.getFruitByFname(fname);
         return fruit == null ? Result.OK() : Result.Fail();
    }

    @PostMapping("/update")
    public Result update(@RequestBody Fruit fruit){ //fruit是请求体参数
        fruitService.updateFruit(fruit);
        return Result.OK();
    }
}
相关推荐
IT古董几秒前
【权限管理】Apache Shiro学习教程
java·apache·shiro·权限
风月歌3 分钟前
基于Spring Boot的海滨体育馆管理系统的设计与实现
java·spring boot·后端
ggdpzhk4 小时前
idea 编辑竖列:alt +shift+insert
java·ide·intellij-idea
hikktn5 小时前
Java 兼容读取WPS和Office图片,结合EasyExcel读取单元格信息
java·开发语言·wps
迪迦不喝可乐5 小时前
软考 高级 架构师 第十一章 面向对象分析 设计模式
java·设计模式
檀越剑指大厂5 小时前
【Java基础】使用Apache POI和Spring Boot实现Excel文件上传和解析功能
java·spring boot·apache
苹果酱05675 小时前
Golang的网络流量分配策略
java·spring boot·毕业设计·layui·课程设计
孑么6 小时前
GDPU Android移动应用 重点习题集
android·xml·java·okhttp·kotlin·android studio·webview
未命名冀6 小时前
微服务面试相关
java·微服务·面试
Heavydrink7 小时前
ajax与json
java·ajax·json