ServletContext
ServletContext 表示Servlet应用程序。每个Web应用程序只有一个上下文。
通过在ServletConfig中调用getServletContext方法,可以获得ServletContext.
GenericServlet
GenericServlet抽象类实现了Servlet和ServletConfig接口,可以使代码简洁。
示例:
package cn.tzsk;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name="DemoGenericServlet",urlPatterns = {"/DemoGenericServlet"},
initParams = {
@WebInitParam(name="admin",value="biao"),
@WebInitParam(name="email",value = "biao@tzsk.cn")
}
)
public class DemoGenericServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
String admin = servletConfig.getInitParameter("admin");
String email = servletConfig.getInitParameter("email");
servletResponse.setContentType("text/html");
PrintWriter writer = servletResponse.getWriter();
writer.print("<html><head></head><body>"
+ "Admin:"+admin+"<br/>Email:"+email +"</body></html>");
}
}
HttpServlet
HttpServlet类继承了 javax.servlet.GenericServlet类。
HttpServlet中的service方法会检验用来发送请求的HTTP方法(通过调用getMethod),然后再调用以下方法之一 doGet,doPost,doHead,doPut,doTrace,doOptions,doDelete.
HttpServlet.class 中service方法
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);
}
}
/*
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
*/
HttpServlet有两个特征是GenericServlet所不具备的:
1、不用覆盖service方法,而是覆盖doGet或doPost或其它方法。
2、使用HttpServletRequest 和 HttpServletResponse,而非 ServletRequest 和 ServletResponse.
HttpServletRequest
HttpServletRequest 表示HTTP环境中的Servlet请求,扩展自servlet.ServletRequest接口,并添加以下方法:
String getContextPath();
返回表示请求上下文的请求URI部分
Cookie[] getCookies();
返回一个Cookie对象数组
String getHeader(String var1);
返回指定HTTP标题的值
String getMethod();
返回生成这个请求的HTTP方法名称
String getQueryString();
返回请求URL中查询字符串
HttpSession getSession();
返回与这个请求相关的会话对象,如没有,将创建一个新的会话对象
HttpSession getSession(boolean var1);
返回与这个请求相关的会话对象,如没有,且参数为True,将创建一个新的会话对象
HttpServletResponse
void addCookie(Cookie var1);
给这个响应对象添加一个cookie
void addHeader(String var1, String var2);
给这个响应对象添加一个header
void sendRedirect(String var1) throws IOException;
发送一条响应码,将浏览器跳转到指定的位置
一个简单的示例:
package cn.tzsk;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/DemoHttpServlet")
public class DemoHttpServlet extends HttpServlet {
private static final long serialVersionUID = 11L;
private static final String TITLE = "简单示例";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doGet(req, resp);
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>"+TITLE+"</title></head>");
writer.println("<body><h1>提交测试</h1>");
writer.println("<form method='post'>");
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>Name:</td>");
writer.println("<td><input name = 'name'/></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Address:</td>");
writer.println("<td><textarea name = 'address' cols='40' rows = 5 ></textarea></td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td> :</td>");
writer.println("<td><input type = 'reset'/><input type='submit'/></td>");
writer.println("</tr>");
writer.println("</table>");
writer.println("</form>");
writer.println("</body>");
writer.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<br/>name:" +req.getParameter("name"));
writer.println("<br/>Address:" +req.getParameter("address"));
}
}
使用部署描述符
部署描述符总是命名为 web.xml,并且放在 WEB-INF目录下。
使用部署描述符的诸多好处:
1、可以将在@WebServlet中没有对等元素的元素,如 load-on-startup无素
2、如果需要修改配置值,如Servlet路径,则不需要重新编译Servlet类;还可以将初始参数传给一个Servlet,并不需要重新编译Servlet类。
3、部署描述符还允许覆盖在Servlet标注中定义的值。Servlet上的WebServlet标注如果同时也在部署描述符中进行声明,那么它将不起作用。也就是说,在Servlet注解标注中存在,并且部署描述符中也存在,则部署描述符中的值起作用,而在Servlet注解标注中存在,并且部署描述符中不存在时,注解标注起作用。