非严谨–Servlet学习总结
- 什么是Servlet?干啥用的?
- Java Server Applet的简称,小服务程序
- 指Java编写的服务器端程序,具有独立平台和协议的特性
- 主要用于交互式浏览和生成数据、动态web内容
- 具体到语言层面指实现了Servlet接口的类,大多数情况下只用于拓展基于HTTP协议的web服务器(继承HttpServlet)
- Servlet的工作工程概述
- web容器(web服务器)接收用户端请求
- 请求发送到Servlet程序
- Servlet响应请求,生成响应内容发送给服务器
- 服务器将响应内容发送给客户端
- Servlet的声明周期
- 调用init方法初始化
- 调用service方法处理请求
- 调用destroy方法销毁
- GC回收
- Servlet接口源码浏览(忽略异常)
void init(ServletConfig var1); void service(ServletRequest var1, ServletResponse var2); void destroy(); ServletConfig getServletConfig(); String getServletInfo();
- GenericServlet源码浏览
public abstract class GenericServlet implements Servlet { private transient ServletConfig config; public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { } public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; public void destroy() { } public ServletConfig getServletConfig() { return this.config; } public String getServletInfo() { return ""; } }
- HttpServlet源码浏览
public abstract class HttpServlet extends GenericServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) { //决定调用doGet()、doPost()等某个方法 } protected void doGet(HttpServletRequest req, HttpServletResponse resp){...} protected void doPost(HttpServletRequest req, HttpServletResponse resp){...} ... }
- Servlet在web.xml中的映射设置
<servlet> <!--给该servlet程序起个霸气的名字--> <servlet-name>hello</servlet-name> <!--servlet程序的全类名--> <servlet-class>com.calmjava.servlet.Servlet01</servlet-class> </servlet> <servlet-mapping> <!--与上边起的名字相同--> <servlet-name>hello</servlet-name> <!--相对工程的浏览器访问URL--> <url-pattern>/servlet01</url-pattern> </servlet-mapping>
- 编写第一个Servlet程序Demo
public class Servlet01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf8"); PrintWriter out = resp.getWriter(); out.write("调用了我的第一个Servlet程序的doGet方法!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- ServletContext概述
- web容器在启动是为每个web程序创建一个ServletContext对象,代表当前web应用
- 一个web应用的所有Servlet共享ServletContext,可以进行通信
- ServletConfig对象中维护了ServletContext对象的引用
- Servlet的应用Demo
- 共享资源
public class Servlet01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置name=calmjava键值对 ServletContext context = getServletContext(); context.setAttribute("name", "calmjava"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } public class Servlet02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取name的值输出到网页 ServletContext context = getServletContext(); resp.setContentType("text/html"); resp.setCharacterEncoding("utf8"); String name = (String)context.getAttribute("name"); resp.getWriter().print(name); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 共享资源
-
- 请求转发(与重定向区别)
public class Servlet03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); RequestDispatcher dispatcher = context.getRequestDispatcher("/servlet映射路径"); dispatcher.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 读取资源文件
public class Servlet05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //注意路径使用了打包后的相对路径 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop = new Properties(); prop.load(is); String username = prop.getProperty("username"); String password = prop.getProperty("password"); is.close(); resp.getWriter().write(username + ":" + password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 请求转发(与重定向区别)
- 关于请求与响应
- web服务器接收http请求,创建代表请求的HttpServletRequest对象和代表响应的HttpServletResponse对象
- HttpServletRequest对象用来获取请求信息,HttpServletResponse对象用来响应信息
- HttpServletResponse
- 写出数据
ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException;
- 设置响应头
void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentLengthLong(long var1); void setContentType(String var1);
- 一些响应状态码
int SC_OK = 200; int SC_BAD_REQUEST = 400; int SC_NOT_FOUND = 404; int SC_BAD_GATEWAY = 502;
- 一些应用
- 输出信息(简单,不做演示)
- 下载文件
public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); //获取文件的绝对路径(当前工程打包后路径+我们填写的字符串) String path = context.getRealPath("WEB-INF/classes/1.png"); //获取文件名(精彩的实现方式) String fileName = path.substring(path.lastIndexOf("\\")+1); //设置响应头让浏览器下载文件 resp.setHeader("Content-Disposition","attachment;filename="+fileName); //获取文件输入流并写出 InputStream is = new FileInputStream(path); ServletOutputStream os = resp.getOutputStream(); int len; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { os.write(buffer,0,len); } //关闭流 os.close(); is.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 重定向
public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* 通过抓包可以看到:状态码设置302 响应头Location:/Web03_war/down */ resp.sendRedirect("/Web03_war/down"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
- 写出数据