1. Servlet中的service, doGet, doPost方法的区别和联系
继承HttpServlet的时候为何一般只重写doGet
和doPost
方法呢?
我们来看一下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
方法(doGet
和doPost
)中给服务器使用。 - 我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。
常用方法
getRequestURI()
——获取请求的资源路径getRequestURL()
——获取请求的统一资源定位符(绝对路径)getRemoteHost()
——获取客户端的 IP 地址getHeader()
——获取请求头getParameter()
——获取请求的参数getParameterValues()
——获取请求的参数(多个值的时候使用)getMethod()
——获取请求的方法 GET 或 POSTsetAttribute(key, value)
——设置域数据getAttribute(key)
——获取域数据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/工程路径/资源路径
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
- 绝对路径
- 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>");
}
}