package com.csn.web; import com.csn.pojo.vo.PageBean; import com.csn.pojo.vo.Pagination; import com.csn.pojo.vo.Result; import com.csn.service.StudentService; import com.csn.util.BaseController; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @WebServlet(urlPatterns = "/student/*") public class StudentServlet extends HttpServlet { private StudentService service = new StudentService(); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置请求和响应编码 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); /*todo:请求分发 优化代码**/ //1.获取方法名(请求地址中的具体需求eg:(student/selectByPage) ) StringBuffer requestURL = request.getRequestURL(); //切割地址 student/selectByPage int Index = requestURL.lastIndexOf("/");//拿到"/"的索引位 赋值给Index //用String的substring(a,b)方法截取字符串 (左包右不包) // substring(a,b)中的参数b,其值最大可以为 父字符串的长度,但并不包含索引值为b的那个字符。 String method = requestURL.substring(Index + 1,requestURL.length());//切割:student/selectByPage => selectByPag 将selectByPag赋值给method方法 /* if(method.equals("selectByPage")) { //分页查询功能 selectByPage(request,response); }else if(method.equals("addStu")) { //添加数据功能 addStu(request,response); } else if(method.equals("updateStu")) { //修改数据功能 updateStu(request,response); } else if(method.equals("deleteStu")) { //删除数据功能 deleteStu(request,response); }*/ /*todo:反射 优化代码*/ //找到要反射的类 try { Class aClass = this.getClass();//=StudentServlet.class //找到类中指定的方法, 方法名method Method m = aClass.getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class); //调用方法 m.setAccessible(true);//暴力反射 忽略访问权限的限制,直接调用 目的invoke方法的实现 权限检查 //invok参数说明: this指调用此方法的对象,request,response 指调用参数 /* *第一个参数:调用底层方法的对象 *其他参数 :用于方法调用的参数 * */ m.invoke(this, request, response);//invoke()/**知识盲区,有机会再研究反射底层**/ } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } private void deleteStu(HttpServletRequest request, HttpServletResponse response) { } private void updateStu(HttpServletRequest request, HttpServletResponse response) { } private void addStu(HttpServletRequest request, HttpServletResponse response) { } private void selectByPage(HttpServletRequest request, HttpServletResponse response) { //获取请求参数 try{ //获取请求体中的json格式参数并映射到Pagination中 Pagination pagination = BaseController.parseJSON2Object(request, Pagination.class); //调用业务层的查询方法 PageBean page = service.selectByPage(pagination); //响应给客户端 //将Result对象转成json,并用响应给前端 BaseController.printResult(response,new Result(true,"查询成功!",page)); } catch (RuntimeException e) { e.printStackTrace(); try { BaseController.printResult(response, new Result(false, "查询失败o(╥﹏╥)o!")); } catch (IOException ex) { ex.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } }
invok()官方API:
invoke
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
- 对带有指定参数的指定对象调用由此
Method
对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。如果底层方法是静态的,那么可以忽略指定的
obj
参数。该参数可以为 null。如果底层方法所需的形参数为 0,则所提供的
args
数组长度可以为 0 或 null。如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。
- 参数:
obj
- 从中调用底层方法的对象args
- 用于方法调用的参数- 返回:
- 使用参数
args
在obj
上指派该对象所表示方法的结果 - 抛出:
IllegalAccessException
- 如果此Method
对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。IllegalArgumentException
- 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。InvocationTargetException
- 如果底层方法抛出异常。NullPointerException
- 如果指定对象为 null,且该方法是一个实例方法。ExceptionInInitializerError
- 如果由此方法引起的初始化失败。