项目实战:中央控制器实现(2)
1、FruitController
- FruitController已经和Web没有关系了,和Web容器解耦,可以脱离Web容器做单元测试
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 {@Autowireprivate 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();} }
2、DispatcherServlet
package com.csdn.mymvc.core; import com.csdn.fruit.dto.Result; import com.csdn.fruit.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 org.junit.Test; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; 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";@Testpublic void uri() {String uri = "/fruit/index";String[] arr = uri.split("/");System.out.println(Arrays.toString(arr));//[, fruit, index]}@Overrideprotected 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或者postString requestMethodStr = req.getMethod().toLowerCase();//get_/indexMethod method = controllerDefinition.getMethodMappingMap().get(requestMethodStr + "_" + methodMapping);Object controllerBean = controllerDefinition.getControllerBean();try {//第 1 步:参数处理//第 2 步:方法调用//调用controllerBean对象中的method方法method.setAccessible(true);Object returnObj = method.invoke(controllerBean, req, resp);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)
1、FruitController
- FruitController已经和Web没有关系了,和Web容器解耦,可以脱离Web容器做单元测试
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 {@Autowireprivate 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();} }
2、DispatcherServlet
package com.csdn.mymvc.core; import com.csdn.fruit.dto.Result; import com.csdn.fruit.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 org.junit.Test; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; 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";@Testpublic void uri() {String uri = "/fruit/index";String[] arr = uri.split("/");System.out.println(Arrays.toString(arr));//[, fruit, index]}@Overrideprotected 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或者postString requestMethodStr = req.getMethod().toLowerCase();//get_/indexMethod method = controllerDefinition.getMethodMappingMap().get(requestMethodStr + "_" + methodMapping);Object controllerBean = controllerDefinition.getControllerBean();try {//第 1 步:参数处理//第 2 步:方法调用//调用controllerBean对象中的method方法method.setAccessible(true);Object returnObj = method.invoke(controllerBean, req, resp);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);}}} }