Servlet复习笔记(3)——为何重写doGet和doPost方法、HttpServletRequest、请求转发、\含义

1. Servlet中的service, doGet, doPost方法的区别和联系

继承HttpServlet的时候为何一般只重写doGetdoPost方法呢?
我们来看一下HttpServlet的源码:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

由此可知,在HttpServlet中实现的service方法只是起到了调度请求的作用。
如果我们重写了service方法, 父类HttpServlet中的service方法就会失效,所以收到的任何请求都会由我们自己覆写的service方法来处理。

2. HttpServletRequest 类

javaweb四大域之二:

  • 每次有请求进入服务器,服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。
  • 然后传递到 service 方法(doGetdoPost)中给服务器使用。
  • 我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。

常用方法

  1. getRequestURI()——获取请求的资源路径
  2. getRequestURL()——获取请求的统一资源定位符(绝对路径)
  3. getRemoteHost()——获取客户端的 IP 地址
  4. getHeader()——获取请求头
  5. getParameter()——获取请求的参数
  6. getParameterValues()——获取请求的参数(多个值的时候使用)
  7. getMethod()——获取请求的方法 GET 或 POST
  8. setAttribute(key, value)——设置域数据
  9. getAttribute(key)——获取域数据
  10. getRequestDispatcher()——获取请求转发对象

示例

public class RequestAPIServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	// i.getRequestURI() 获取请求的资源路径
	System.out.println("URI => " + req.getRequestURI());
	// ii.getRequestURL() 获取请求的统一资源定位符(绝对路径)
	System.out.println("URL => " + req.getRequestURL());
	// iii.getRemoteHost() 获取客户端的 ip 地址

	System.out.println("客户端 ip 地址 => " + req.getRemoteHost());
	// iv.getHeader() 获取请求头
	System.out.println("请求头 User-Agent ==>> " + req.getHeader("User-Agent"));
	// vii.getMethod() 获取请求的方式 GET 或 POST
	System.out.println( "请求的方式 ==>> " + req.getMethod() );
	}
}
<body> <form>action="http://localhost:8080/07_servlet/parameterServlet" method="get"> 
用户名:<input type="text" name="username"><br/> 
密码:<input type="password" name="password"><br/> 
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++ 
<input type="checkbox" name="hobby" value="java">Java <input type="checkbox" name="hobby" value="js">JavaScript<br/> 
<input type="submit">
</form>
</body>
public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        System.out.println("-----------doGet-----------");
        
        //doGet 请求的中文乱码解决
        //1 先以 iso8859-1 进行编码
        String username = req.getParameter("username");
		//2 再以 utf-8 进行解码
		username = new String(username.getBytes("iso-8859-1"), "UTF-8");
		
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");
        System.out.println(username + password + Arrays.asList(hobby));

        
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	// POST 请求的中文乱码解决
    	// 设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
        req.setCharacterEncoding("UTF-8");
        System.out.println("-------------doPost--------------");
        System.out.println(req.getParameter("username"));
        System.out.println(req.getParameter("password"));
        System.out.println(Arrays.toString(req.getParameterValues("hobby")));
    }
}

请求的转发

在这里插入图片描述
示例:

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println("servlet1:"+username);
        req.setAttribute("key","柜台1");
        RequestDispatcher requestdispatcher = req.getRequestDispatcher("/servlet2");
        requestdispatcher.forward(req,resp);
    }
}

public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException { 
// 获取请求的参数(办事的材料)查看 
String username = req.getParameter("username"); System.out.println("在 Servlet2(柜台 2)中查看参数(材料):" + username);
// 查看柜台1 是否有盖章 
Object key1 = req.getAttribute("key1"); System.out.println("柜台 1 是否有章:" + key1);
// 处理自己的业务 
System.out.println("Servlet2 处理自己的业务 ");
} }

番外1:base 标签

常见的url路径形式分别有相对路径与绝对路径,如果base标签指定了目标,浏览器将通过这个目标来解析当前文档中的所有相对路径,包括的标签有(a、img、link、form),也就是说,浏览器解析时会在路径前加上base给的目标,而页面中的相对路径也都转换成了绝对路径。使用了base标签就应带上href属性和target属性。

因为所有相对路径工作时都会参照浏览器地址栏中的地址进行跳转,所以会产生一些错误。例如需求:使用a/b/c.html跳转到index.html,再跳转回来。若使用转发来实现就会出现错误。

番外2:JavaWeb 中相对路径和绝对路径

在 javaWeb 中,路径分为相对路径和绝对路径两种:
相对路径是:
. ——表示当前目录
… ——表示上一级目录

绝对路径 http://ip:port/工程路径/资源路径

在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。

  1. 绝对路径
  2. base+相对路径

番外3:JavaWeb 中 / 的含义

以访问Example工程下web(Ecplise中是WebContent)目录下的index.jsp为例。
直接上结论:

  • 浏览器发起请求:“/”表示“Tomcat/webapps”目录。调用资源的时候需要写/Example/index.jsp(须带上工程名)。
  • 服务器发起请求:“/”表示“Tomcat/webapps/Example(Example为工程名)”的目录,调用资源的时候写/index.jsp。

其中请求的分类如下:

重定向、转发、a标签(超链接)、表单提交

public class PathServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1、重定向:浏览器发起
        response.sendRedirect("/Example/index.jsp");

        //2、转发:服务器发起
        request.getRequestDispatcher("/index.jsp").forward(request, response);

        //3、超链接:浏览器发起
        response.setContentType("text/html");
        response.getWriter().write("<thml><head></head><body><a href='/Example/index.jsp'>index.jsp<a></body></html>");

        //4、表单提交:浏览器发起
        response.setContentType("text/html");
        response.getWriter().write("<thml><head></head><body><form action='/Example/index.jsp'><input type='submit' value='to index.jsp'/></form></body></html>");
    }

}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值