使用反射和HttpServlet类制作一个简单的web层框架

1.什么是 Servlet

1、Servlet 是 JavaEE 规范之一。规范就是接口
2、Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
3、Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

2.手动实现 Servlet 程序

1、编写一个类去实现 Servlet 接口
2、实现 service 方法,处理请求,并响应数据
3、到 web.xml 中去配置 servlet 程序的访问地址

public class HelloServlet implements Servlet { 
/*** service 方法是专门用来处理请求和响应的 
* @param servletRequest 
* @param servletResponse 
* @throws ServletException 
* @throws IOException 
*/ 
@Override 
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { 
System.out.println("Hello Servlet 被访问了"); 
} 
}

web.xml 中的配置:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> 
<!-- servlet 标签给 Tomcat 配置 Servlet 程序 --> 
<servlet> <!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) --> 
<servlet-name>HelloServlet</servlet-name> 
<!--servlet-class 是 Servlet 程序的全类名--> 
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class> 
</servlet> 
<!--servlet-mapping 标签给 servlet 程序配置访问地址--> 
<servlet-mapping> 
<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用--> 
<servlet-name>HelloServlet</servlet-name> 
<!--url-pattern 标签配置访问地址 <br/> / 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径 <br/> /hello 表示地址为:http://ip:port/工程路径/hello <br/> --> 
<url-pattern>/hello</url-pattern> 
</servlet-mapping> 
</web-app>

3.HTTP实现doGet或doPost请求原理介绍

1、浏览器发送请求到HttpServ类调用HttpServ的service(servletRequest, servletReponse)方法
2、由于没有找到这个方法,去调用父类(HttpServlet) 的同名方法。
3、父类的service方法将ServletRequest req请求转换成HttpServletRequest请求,再去调用service(request, response) 方法。
4、调用的service(request, response) 方法功能是判断用户发出是什么请求,如果是get则调用子类(HttpSevr)的doGet方法,如果是post则调用子类(HttpSevr)的doPost方法。该方法是在HttpServlet中。

4.简易的反射实现一个HttpServlet框架

通常在web应用中处理web亲求需要使用servlet,继承HttpServlet实现do/get方法,而当请求的种类多了之后,就会不断地编写新的do/get方法来实现请求和响应,然而我们写代码的目的不就是为了减少工作量(偷懒)么?

下面的代码通过java反射技术,在请求传到服务器时,调用相应的方法实现请求,controller下的类只需要继承这个类,实现相应的业务逻辑,就能够调用相应的方法实现do/get

public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决post请求中文乱码问题
        // 一定要在获取请求参数之前调用才有效
        req.setCharacterEncoding("UTF-8");  //服务器字符集设置为UTF-8  解决响应的中文乱码

        resp.setHeader("Content-type","text/hetml;charset=UTF-8");
        //通过响应头,设置浏览器也使用UTF-8

        String action = req.getParameter("action");
        try {
            // 获取action业务鉴别字符串,获取相应的业务 方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
//            System.out.println(method);
            // 调用目标业务 方法
            method.setAccessible(true);
            method.invoke(this, req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
posted @ 2020-12-22 15:47  小脑斧不可爱  阅读(88)  评论(0编辑  收藏  举报