JavaWeb——Servlet
前言:什么是Servlet?
Servlet是采用Java写的Web服务器端程序。
当客户端(浏览器)向服务器端发起请求时,服务器将请求(Request)进行封装后便调用Servlet程序处理请求,Servlrt将处理后的结果(Response)返回给服务器,服务器对结果进行封装后返回给客户端。
我们在学习开发中往往采用TomCat来作为服务器,由TomCat来调用Servlet处理Web请求。
Servlet
Servlet中的方法
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
当客户端向服务器发起请求时,服务器启动Servlet,Servlet首先调用 getServletConfig() 方法获得Servlet相关配置,并作为参数传递给 init() 方法,init() 方法用来初始化Servlet,Servlet初始化完成后就会调用 service() 方法处理请求 ,getServletInfo() 可以获得Servlet的一段描述信息,当请求处理结束后,便会调用 destroy() 方法销毁Servlet。这也是Servlet的生命周期。
ServletRequest 及 ServletResponse
Servlet在调用 service() 方法前会生成ServletRequest对象和ServletResponse对象。
我们可以通过ServletRequest中的方法来获取请求的相关信息:
public interface ServletRequest {
int getContentLength();//返回请求主体的字节数
String getContentType();//返回主体的MIME类型
String getParameter(String var1);//返回请求参数的值
}
可以通过ServletResponse中的方法自定义返回结果:
public interface ServletResponse {
String getCharacterEncoding();// 获取字符编码格式
String getContentType();//获取内容类型
ServletOutputStream getOutputStream() throws IOException;//获取二进制输出流,可用于(通过缓冲区)向响应体中书写内容
PrintWriter getWriter() throws IOException;//获取文本输出流,可用于(通过缓冲区)向响应体中书写内容
void setCharacterEncoding(String var1);// 设置字符编码格式
void setContentLength(int var1);// 设置响应体长度
void setContentType(String var1);// 设置响应数据类型
void setBufferSize(int var1);// 设置缓冲区大小
int getBufferSize();// 获取缓冲区大小
void flushBuffer() throws IOException;// 刷新缓冲区
void resetBuffer();// 清空缓冲区
boolean isCommitted();// 响应是否已提交
void reset();// 清空缓冲区以及响应状态码和响应头
}
GenericServlet
直接实现Servlet接口较为复杂,我们需要实现其中的全部方法。GenericServlet抽象类的出现很好的解决了这个问题:
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
private transient ServletConfig config;
public GenericServlet() {
}
public void destroy() {
}
public String getInitParameter(String name) {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameter(name);
}
}
public Enumeration<String> getInitParameterNames() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameterNames();
}
}
public ServletConfig getServletConfig() {
return this.config;
}
public ServletContext getServletContext() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletContext();
}
}
public String getServletInfo() {
return "";
}
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
}
public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
public String getServletName() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletName();
}
}
}
GenericServlet抽象类为我们提供了Servlet接口中方法的默认实现,我们可以只实现我们需要的方法。
HttpServlet
在实际的开发中,我们更常使用HttpServlet抽象类,它继承了GenericServlet抽象类。
HttpServlet覆盖了GenericServlet中的 service() 方法,在方法中调用了提供的另一个 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 = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified) {
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);
}
}
根据不同的Http请求类型调用不同的doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete方法,当我们需要实现具体的逻辑时只需要覆盖相应的do方法即可。
HttpServletRequest
HttpServletRequest继承自ServletRequest,新增了几个方法:
String getContextPath();//返回请求上下文的请求URI部分
Cookie[] getCookies();//返回一个cookie对象数组
String getHeader(String var1);//返回指定HTTP标题的值
String getMethod();//返回生成这个请求HTTP的方法名称
String getQueryString();//返回请求URL中的查询字符串
HttpSession getSession();//返回与这个请求相关的会话对象
HttpServletResponse
HttpServletResponse继承自ServletResPonse,新增了几个方法:
void addCookie(Cookie var1);//给这个响应添加一个cookie
void addHeader(String var1, String var2);//给这个请求添加一个响应头
void setHeader(String name, String value);// 设置响应头的值
void sendRedirect(String var1) throws IOException;//发送一条响应码,将浏览器跳转到指定的位置
void setStatus(int var1);//设置响应行的状态码