• 项目实战:中央控制器实现(3)-优化Controller,处理普通的请求参数


     1、DispatcherServlet

    1. package com.csdn.mymvc.core;
    2. import com.csdn.fruit.dto.Result;
    3. import com.csdn.fruit.util.ResponseUtil;
    4. import jakarta.servlet.RequestDispatcher;
    5. import jakarta.servlet.ServletContext;
    6. import jakarta.servlet.ServletException;
    7. import jakarta.servlet.annotation.WebServlet;
    8. import jakarta.servlet.http.HttpServlet;
    9. import jakarta.servlet.http.HttpServletRequest;
    10. import jakarta.servlet.http.HttpServletResponse;
    11. import org.junit.Test;
    12. import java.io.IOException;
    13. import java.lang.reflect.InvocationTargetException;
    14. import java.lang.reflect.Method;
    15. import java.lang.reflect.Parameter;
    16. import java.util.Arrays;
    17. import java.util.Map;
    18. @WebServlet("/*")
    19. public class DispatcherServlet extends HttpServlet {
    20. private final String BEAN_FACTORY = "beanFactory";
    21. private final String CONTROLLER_BEAN_MAP = "controllerBeanMap";
    22. @Test
    23. public void uri() {
    24. String uri = "/fruit/index";
    25. String[] arr = uri.split("/");
    26. System.out.println(Arrays.toString(arr));//[, fruit, index]
    27. }
    28. @Override
    29. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    30. String[] staticResourceSuffixes = {".html", ".jsp", ".jpg", ".png", ".gif", ".css", ".js", ".ico"};
    31. String uri = req.getRequestURI();
    32. if (Arrays.stream(staticResourceSuffixes).anyMatch(uri::endsWith)) {
    33. RequestDispatcher defaultDispatcher = req.getServletContext().getNamedDispatcher("default");
    34. defaultDispatcher.forward(req, resp);
    35. } else {
    36. String[] arr = uri.split("/");
    37. if (arr == null || arr.length != 3) {
    38. throw new RuntimeException(uri + "非法!");
    39. }
    40. //[, fruit, index]
    41. String requestMapping = "/" + arr[1];
    42. String methodMapping = "/" + arr[2];
    43. ServletContext application = getServletContext();
    44. ControllerDefinition controllerDefinition = ((Map) application.getAttribute(CONTROLLER_BEAN_MAP))
    45. .get(requestMapping);
    46. if (controllerDefinition == null) {
    47. throw new RuntimeException(requestMapping + "对应的controller组件不存在!");
    48. }
    49. //获取请求方式,例如:get或者post
    50. String requestMethodStr = req.getMethod().toLowerCase();
    51. //get_/index
    52. Method method = controllerDefinition.getMethodMappingMap().get(requestMethodStr + "_" + methodMapping);
    53. Object controllerBean = controllerDefinition.getControllerBean();
    54. try {
    55. //第 1 步:参数处理
    56. //获取method方法上的参数
    57. Parameter[] parameters = method.getParameters();
    58. Object[] parameterValues = new Object[parameters.length];
    59. for (int i = 0; i < parameters.length; i++) {
    60. Parameter parameter = parameters[i];
    61. //获取参数名称
    62. //JDK8之前,通过反射获取到参数对象(Parameter对象)
    63. //然后通过parameter.getName()方法是得不到形参的名称的,返回的是arg0,arg1,arg2....
    64. //JDK8开始,反射技术得到的Class中可以包含方法形参的名称,不过需要做一个额外的设置:
    65. //java compiler中添加一个参数:-parameters
    66. String paramName = parameter.getName();
    67. String paramValueStr = req.getParameter(paramName);
    68. //获取参数的类型
    69. String parameterTypeName = parameter.getType().getName();
    70. Object parameterValue = switch (parameterTypeName) {
    71. case "java.lang.String"-> paramValueStr;
    72. case "java.lang.Integer"-> Integer.parseInt(paramValueStr);
    73. default -> null;
    74. };
    75. parameterValues[i] = parameterValue;
    76. }
    77. //第 2 步:方法调用
    78. //调用controllerBean对象中的method方法
    79. method.setAccessible(true);
    80. Object returnObj = method.invoke(controllerBean, parameterValues);
    81. if (returnObj != null && returnObj instanceof Result) {
    82. Result result= (Result) returnObj;
    83. ResponseUtil.print(resp,result);
    84. }
    85. } catch (IllegalAccessException e) {
    86. e.printStackTrace();
    87. throw new RuntimeException(e);
    88. } catch (InvocationTargetException e) {
    89. e.printStackTrace();
    90. throw new RuntimeException(e);
    91. }
    92. }
    93. }
    94. }

     2、FruitController

    1. package com.csdn.fruit.controller;
    2. import com.csdn.fruit.dto.PageInfo;
    3. import com.csdn.fruit.dto.PageQueryParam;
    4. import com.csdn.fruit.dto.Result;
    5. import com.csdn.fruit.pojo.Fruit;
    6. import com.csdn.fruit.service.FruitService;
    7. import com.csdn.mymvc.annotation.*;
    8. @Controller
    9. @RequestMapping("/fruit")
    10. public class FruitController {
    11. @Autowire
    12. private FruitService fruitService;
    13. @GetMapping("/index")
    14. public Result index(Integer pageNo,String keyword) {
    15. if (pageNo == null) {
    16. pageNo = 1;
    17. }
    18. if (keyword == null) {
    19. keyword = "";
    20. }
    21. PageQueryParam pageQueryParam = new PageQueryParam(pageNo, 5, keyword);
    22. PageInfo pageInfo = fruitService.getFruitPageInfo(pageQueryParam);
    23. return Result.OK(pageInfo);
    24. }
    25. @PostMapping("/add")
    26. public Result add(@RequestBody Fruit fruit) {
    27. fruitService.addFruit(fruit);
    28. return Result.OK();
    29. }
    30. @GetMapping("/del")
    31. public Result del(Integer fid){
    32. fruitService.delFruit(fid);
    33. return Result.OK();
    34. }
    35. @GetMapping("/edit")
    36. public Result edit(Integer fid){
    37. Fruit fruit = fruitService.getFruitById(fid);
    38. return Result.OK(fruit);
    39. }
    40. @GetMapping("/getFname")
    41. public Result getFname(String fname){ //fname是请求参数
    42. Fruit fruit = fruitService.getFruitByFname(fname);
    43. return fruit == null ? Result.OK() : Result.Fail();
    44. }
    45. @PostMapping("/update")
    46. public Result update(@RequestBody Fruit fruit){ //fruit是请求体参数
    47. fruitService.updateFruit(fruit);
    48. return Result.OK();
    49. }
    50. }

     

  • 相关阅读:
    工具及方法 - TagSpaces
    博士论文——相似度
    全网最全!!Qt实现图片旋转及图片旋转动画的几种方式
    Who will wash the dishes Privacy Policy
    设计模式-Observer模式(观察者模式)
    分享一下微信公众号怎么实现积分商城功能
    Java集合类——ArrayList(扩容机制)
    【无标题】SQL数据库动态生成月份表A,并从B表插入数据然后删除B表数据
    ITSM和ITIL
    Lua解释器裁剪
  • 原文地址:https://blog.csdn.net/m0_65152767/article/details/134298002