烟台哪里做网站好,网站推广基本方法,无域名网站 能否被百度,医院建设网站的作用#x1f600;前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-RequestParam #x1f3e0;个人主页#xff1a;尘觉主页
#x1f9d1;个人简介#xff1a;大家好#xff0c;我是尘觉#xff0c;希望我的文章可以帮助到大家#xff0c… 前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-RequestParam 个人主页尘觉主页
个人简介大家好我是尘觉希望我的文章可以帮助到大家您的满意是我的动力 在csdn获奖荣誉: csdn城市之星2名 Java全栈群星计划top前5 端午大礼包获得者 欢迎大家这里是CSDN我总结知识的地方欢迎来到我的博客感谢大家的观看 如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦 文章目录 实现任务阶段 6- 完成控制器方法获取参数-RequestParam功能说明完成任务说明- 后端 Handler 的目标方法代码完成完成: 将方法的 HttpServletRequest 和 HttpServletResponse 参数封装到参数数组进行反射调用修改WyxDispatcherServlet.java类完成测试 ❤️完成: 在方法参数 指定 RequestParam 的参数封装到参数数组进行反射调用- 测试页面- 后端 Handler 的目标方法创建自定义注解RequestParam修改WyxDispatcherServlet.java接口类修改MonsterSer viceImpl.java实现类修改MonsterController修改WyxDispatcherServlet.java类getIndexRequestParameterIndex方法完成测试 (Redeploy Tomcat 即 可 ) 完成: 在方法参数 没有指定 RequestParam 按照默认参数名获取值, 进行反射调用修改MonsterController修改WyxDispatcherServlet.java类得 到 控 制 器 方 法 的 参 数 名 注意点击 maven 管理clean 项目在重启一下 tomcat ,完成测试后台:如果请求参数和方法参数不一致 总结 实现任务阶段 6- 完成控制器方法获取参数-RequestParam
功能说明
自定义RequestParam 和 方法参数名获取参数
完成任务说明 - 后端 Handler 的目标方法 RequestMapping(value “/monster/find”) public void findMonstersByName(HttpServletRequest request, HttpServletResponse response, RequestParam(value “name”) String name) { //代码… } 代码完成
完成: 将方法的 HttpServletRequest 和 HttpServletResponse 参数封装到参数数组进行反射调用
● 代码实现, 说明整个实现思路就是参考 SpringMVC 规范
修改WyxDispatcherServlet.java类 private void executeDispatch(HttpServletRequest request,HttpServletResponse response) {WyxHandler wyxHandler getWyxHandler(request);try {if (null wyxHandler) {//说明用户请求的路径/资源不存在response.getWriter().print(h1404 NOT FOUND/h1);} else {//匹配成功, 反射调用控制器的方法//目标将: HttpServletRequest 和 HttpServletResponse封装到参数数组//1. 得到目标方法的所有形参参数信息[对应的数组]Class?[] parameterTypes wyxHandler.getMethod().getParameterTypes();//2. 创建一个参数数组[对应实参数组], 在后面反射调用目标方法时会使用到Object[] params new Object[parameterTypes.length];//3遍历parameterTypes形参数组,根据形参数组信息将实参填充到实参数组for (int i 0; i parameterTypes.length; i) {//取出每一个形参类型Class? parameterType parameterTypes[i];//如果这个形参是HttpServletRequest, 将request填充到params//在原生SpringMVC中,是按照类型来进行匹配这里简化使用名字来进行匹配if (HttpServletRequest.equals(parameterType.getSimpleName())) {params[i] request;} else if (HttpServletResponse.equals(parameterType.getSimpleName())) {params[i] response;}}//wyxHandler.getMethod()// .invoke(wyxHandler.getController(),request,response);//反射调用目标方法Object result wyxHandler.getMethod().invoke(wyxHandler.getController(), params);
}完成测试
(启动 tomcat), 浏览器输入 http://localhost:8080/monster/list , 仍然可以看 到正确的返回 ❤️完成: 在方法参数 指定 RequestParam 的参数封装到参数数组进行反射调用
- 测试页面 - 后端 Handler 的目标方法 RequestMapping(value “/monster/find”) public void findMonstersByName(HttpServletRequest request, HttpServletResponse response, RequestParam(value “name”) String name) { //代码… } 创建自定义注解RequestParam
Target(ElementType.PARAMETER)
Retention(RetentionPolicy.RUNTIME)
Documented
public interface RequestParam {String value() default ;
}修改WyxDispatcherServlet.java接口类
public interface MonsterService {public ListMonster listMonsters();public ListMonster findMonstersByName(String name);
}修改MonsterSer viceImpl.java实现类
Service
public class MonsterServiceImpl implements MonsterService {Overridepublic ListMonster listMonster() {//这里就模拟数据-DBListMonster monsters new ArrayList();monsters.add(new Monster(100, 牛魔王, 芭蕉扇, 400));monsters.add(new Monster(200, 老猫妖怪, 抓老鼠, 200));return monsters;}Overridepublic ListMonster findMonsterByName(String name) {//这里就模拟数据-DBListMonster monsters new ArrayList();monsters.add(new Monster(100, 牛魔王, 芭蕉扇, 400));monsters.add(new Monster(200, 老猫妖怪, 抓老鼠, 200));monsters.add(new Monster(300, 大象精, 运木头, 100));monsters.add(new Monster(400, 黄袍怪, 吐烟雾, 300));monsters.add(new Monster(500, 白骨精, 美人计, 800));//创建集合返回查询到的monster集合ListMonster findMonsters new ArrayList();//遍历monsters,返回满足条件for (Monster monster : monsters) {if (monster.getName().contains(name)) {findMonsters.add(monster);}}return findMonsters;}修改MonsterController
Controller
public class MonsterController {//AutoWired表示要完成属性的装配.AutoWiredprivate MonsterService monsterService;RequestMapping(value /monster/find)public void findMonsterByName(HttpServletRequest request,HttpServletResponse response,RequestParam(valuename) String name) {//设置编码和返回类型response.setContentType(text/html;charsetutf-8);System.out.println(--接收到的name--- name);StringBuilder content new StringBuilder(h1妖怪列表信息/h1);//调用monsterServiceListMonster monsters monsterService.findMonsterByName(name);content.append(table border1px width400px styleborder-collapse:collapse);for (Monster monster : monsters) {content.append(trtd monster.getId() /tdtd monster.getName() /tdtd monster.getSkill() /tdtd monster.getAge() /td/tr);}content.append(/table);//获取writer返回信息try {PrintWriter printWriter response.getWriter();printWriter.write(content.toString());} catch (IOException e) {e.printStackTrace();}}
}修改WyxDispatcherServlet.java类 private void executeDispatch(HttpServletRequest request,HttpServletResponse response) {WyxHandler wyxHandler getWyxHandler(request);try {if (null wyxHandler) {//说明用户请求的路径/资源不存在response.getWriter().print(h1404 NOT FOUND/h1);} else {//匹配成功, 反射调用控制器的方法//目标将: HttpServletRequest 和 HttpServletResponse封装到参数数组//1. 得到目标方法的所有形参参数信息[对应的数组]Class?[] parameterTypes wyxHandler.getMethod().getParameterTypes();//2. 创建一个参数数组[对应实参数组], 在后面反射调用目标方法时会使用到Object[] params new Object[parameterTypes.length];//3遍历parameterTypes形参数组,根据形参数组信息将实参填充到实参数组for (int i 0; i parameterTypes.length; i) {//取出每一个形参类型Class? parameterType parameterTypes[i];//如果这个形参是HttpServletRequest, 将request填充到params//在原生SpringMVC中,是按照类型来进行匹配老师这里简化使用名字来进行匹配if (HttpServletRequest.equals(parameterType.getSimpleName())) {params[i] request;} else if (HttpServletResponse.equals(parameterType.getSimpleName())) {params[i] response;}}//将http请求参数封装到params数组中, 提示要注意填充实参的时候顺序问题//1. 获取http请求的参数集合//解读//http://localhost:8080/monster/find?name牛魔王hobby打篮球hobby喝酒//2. 返回的MapString,String[] String:表示http请求的参数名// String[]:表示http请求的参数值,为什么是数组////处理提交的数据中文乱码request.setCharacterEncoding(utf-8);MapString, String[] parameterMap request.getParameterMap();//2. 遍历parameterMap 将请求参数按照顺序填充到实参数组paramsfor (Map.EntryString, String[] entry : parameterMap.entrySet()) {//取出key这name就是对应请求的参数名String name entry.getKey();//说明:这里只考虑提交的参数是单值的情况即不考虑类似checkbox提示的数据// 这里做了简化如果考虑多值情况也不难..String value entry.getValue()[0];//我们得到请求的参数对应目标方法的第几个形参然后将其填充//这里专门编写一个方法得到请求的参数对应的是第几个形参int indexRequestParameterIndex getIndexRequestParameterIndex(wyxHandler.getMethod(), name);if (indexRequestParameterIndex ! -1) {//找到对应的位置params[indexRequestParameterIndex] value;} else {//一会写}/*** 解读* 1. 下面这样写法其实是针对目标方法是 m(HttpServletRequest request , HttpServletResponse response)* 2. 这里准备将需要传递给目标方法的 实参封装到参数数组》然后以反射调用的方式传递给目标方法* 3. public Object invoke(Object obj, Object... args)..*///wyxHandler.getMethod()// .invoke(wyxHandler.getController(),request,response);//反射调用目标方法wyxHandler.getMethod().invoke(wyxHandler.getController(), params);} catch (Exception e) {e.printStackTrace();}getIndexRequestParameterIndex方法 public int getIndexRequestParameterIndex(Method method, String name) {//1.得到method的所有形参参数Parameter[] parameters method.getParameters();for (int i 0; i parameters.length; i) {//取出当前的形参参数Parameter parameter parameters[i];//判断parameter是不是有RequestParam注解boolean annotationPresent parameter.isAnnotationPresent(RequestParam.class);if (annotationPresent) {//说明有RequestParam//取出当前这个参数的 RequestParam(value xxx)RequestParam requestParamAnnotation parameter.getAnnotation(RequestParam.class);String value requestParamAnnotation.value();//这里就是匹配的比较if (name.equals(value)) {return i;//找到请求的参数对应的目标方法的形参的位置}}}//如果没有匹配成功就返回-1return -1;}完成测试 (Redeploy Tomcat 即 可 )
浏览器输入http://localhost:8080/monster/find?name牛魔王 完成: 在方法参数 没有指定 RequestParam 按照默认参数名获取值, 进行反射调用
修改MonsterController RequestMapping(value /monster/find)public void findMonsterByName(HttpServletRequest request,HttpServletResponse response,String name) {//设置编码和返回类型response.setContentType(text/html;charsetutf-8);System.out.println(--接收到的name--- name);StringBuilder content new StringBuilder(h1妖怪列表信息/h1);//调用monsterServiceListMonster monsters monsterService.findMonsterByName(name);content.append(table border1px width400px styleborder-collapse:collapse);for (Monster monster : monsters) {content.append(trtd monster.getId() /tdtd monster.getName() /tdtd monster.getSkill() /tdtd monster.getAge() /td/tr);}content.append(/table);//获取writer返回信息try {PrintWriter printWriter response.getWriter();printWriter.write(content.toString());} catch (IOException e) {e.printStackTrace();}}修改WyxDispatcherServlet.java类 private void executeDispatch(HttpServletRequest request,HttpServletResponse response) {WyxHandler wyxHandler getWyxHandler(request);try {if (null wyxHandler) {//说明用户请求的路径/资源不存在response.getWriter().print(h1404 NOT FOUND/h1);} else {//匹配成功, 反射调用控制器的方法//目标将: HttpServletRequest 和 HttpServletResponse封装到参数数组//1. 得到目标方法的所有形参参数信息[对应的数组]Class?[] parameterTypes wyxHandler.getMethod().getParameterTypes();//2. 创建一个参数数组[对应实参数组], 在后面反射调用目标方法时会使用到Object[] params new Object[parameterTypes.length];//3遍历parameterTypes形参数组,根据形参数组信息将实参填充到实参数组for (int i 0; i parameterTypes.length; i) {//取出每一个形参类型Class? parameterType parameterTypes[i];//如果这个形参是HttpServletRequest, 将request填充到params//在原生SpringMVC中,是按照类型来进行匹配这里简化使用名字来进行匹配if (HttpServletRequest.equals(parameterType.getSimpleName())) {params[i] request;} else if (HttpServletResponse.equals(parameterType.getSimpleName())) {params[i] response;}}//将http请求参数封装到params数组中, 提示要注意填充实参的时候顺序问题//1. 获取http请求的参数集合//解读//http://localhost:8080/monster/find?name牛魔王hobby打篮球hobby喝酒//2. 返回的MapString,String[] String:表示http请求的参数名// String[]:表示http请求的参数值,为什么是数组////处理提交的数据中文乱码request.setCharacterEncoding(utf-8);MapString, String[] parameterMap request.getParameterMap();//2. 遍历parameterMap 将请求参数按照顺序填充到实参数组paramsfor (Map.EntryString, String[] entry : parameterMap.entrySet()) {//取出key这name就是对应请求的参数名String name entry.getKey();//说明:这里只考虑提交的参数是单值的情况即不考虑类似checkbox提示的数据// 这里做了简化如果小伙伴考虑多值情况也不难..String value entry.getValue()[0];//我们得到请求的参数对应目标方法的第几个形参然后将其填充//这里专门编写一个方法得到请求的参数对应的是第几个形参int indexRequestParameterIndex getIndexRequestParameterIndex(wyxHandler.getMethod(), name);if (indexRequestParameterIndex ! -1) {//找到对应的位置params[indexRequestParameterIndex] value;} else {//说明并没有找到RequestParam注解对应的参数,就会使用默认的机制进行配置[待..]//思路//1. 得到目标方法的所有形参的名称-专门编写方法获取形参名//2. 对得到目标方法的所有形参名进行遍历,如果匹配就把当前请求的参数值填充到paramsListString parameterNames getParameterNames(wyxHandler.getMethod());for (int i 0; i parameterNames.size(); i) {//如果请求参数名和目标方法的形参名一样说明匹配成功if (name.equals(parameterNames.get(i))) {params[i] value;//填充到实参数组break;}}}}/*** 解读* 1. 下面这样写法其实是针对目标方法是 m(HttpServletRequest request , HttpServletResponse response)* 2. 这里准备将需要传递给目标方法的 实参封装到参数数组》然后以反射调用的方式传递给目标方法* 3. public Object invoke(Object obj, Object... args)..*///wyxHandler.getMethod()// .invoke(wyxHandler.getController(),request,response);//反射调用目标方法Object result wyxHandler.getMethod().invoke(wyxHandler.getController(), params);
} catch (Exception e) {
e.printStackTrace();
}public ListString getParameterNames(Method method) {ListString parametersList new ArrayList();//获取到所以的参数名-这里有一个小细节//在默认情况下 parameter.getName() 得到的名字不是形参真正名字//而是 [arg0, arg1, arg2...], 这里我们要引入一个插件使用java8特性这样才能解决Parameter[] parameters method.getParameters();//遍历parameters 取出名称放入parametersListfor (Parameter parameter : parameters) {parametersList.add(parameter.getName());}System.out.println(目标方法的形参列表 parametersList);return parametersList;}得 到 控 制 器 方 法 的 参 数 名
比 如 public void findMonstersByName(HttpServletRequest request, HttpServletResponse response, RequestParam(value “name”) String name) request, response, name
注意
在默认情况下返回的并不是 request, response ,name 而是 arg0, arg1,arg2需要使用到 jdk8 的新特性并需要在 pom.xml 配置 maven 编译插件(可以百度搜索到)才能得到 request, response, name plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.7.0/versionconfigurationsource1.8/sourcetarget1.8/targetcompilerArgsarg-parameters/arg/compilerArgsencodingutf-8/encoding/configuration/plugin点击 maven 管理clean 项目在重启一下 tomcat ,完成测试 后台: 如果请求参数和方法参数不一致 总结
本文完成了任务阶段 6-完成控制器方法获取参数-RequestParam下一阶段完成 实现任务阶段 7- 完成简单视图解析 自己实现 SpringMVC 底层机制 核心分发 控制器 Controller 和 Service 注入容器 对象自动装配 控制器 方法获取参数 视图解析 返回 JSON 格式数系列
第一篇-自己实现 SpringMVC 底层机制 系列之搭建 SpringMVC 底层机制开发环境和开发 WyxDispatcherServlet_springmvc分发器
第二篇-自己实现 SpringMVC 底层机制 系列之–实现任务阶段 2- 完成客户端浏览器可以请求控制层
第三篇-自己实现 SpringMVC 底层机制 系列之–实现任务阶段 3- 从 web.xml动态获取 wyxspringmvc.xml
第四篇- 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义Service 注解功能
第五篇- 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 5- 完成 Spring 容器对象的自动装配 -Autowried 热门专栏推荐 想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集 linux合集
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持
欢迎大家加入我的社区 尘觉社区 文章到这里就结束了如果有什么疑问的地方请指出诸佬们一起来评论区一起讨论 希望能和诸佬们一起努力今后我们一起观看感谢您的阅读 如果帮助到您不妨3连支持一下创造不易您们的支持是我的动力