Unit03: 容器对路径的处理 、 Servlet特性
案例一:查询,增加员工:
- 重定向
- 处理请求资源路径
目录结构:
案例代码:
package dao; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import entity.Emp; public class EmpDao implements Serializable { public List<Emp> findAll() { List<Emp> list = new ArrayList<Emp>(); Emp e1 = new Emp(); e1.setEmpno(1); e1.setEname("唐僧"); e1.setJob("师父"); e1.setSal(9000.0); list.add(e1); Emp e2 = new Emp(); e2.setEmpno(2); e2.setEname("悟空"); e2.setJob("徒弟"); e2.setSal(5000.0); list.add(e2); Emp e3 = new Emp(); e3.setEmpno(3); e3.setEname("八戒"); e3.setJob("徒弟"); e3.setSal(6000.0); list.add(e3); return list; } public void save(Emp e) { System.out.println( "增加员工:" + e.getEname()); } }
package entity; import java.io.Serializable; public class Emp implements Serializable { private Integer empno; private String ename; private String job; private Double sal; public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Double getSal() { return sal; } public void setSal(Double sal) { this.sal = sal; } }
package web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dao.EmpDao; import entity.Emp; public class AddEmpServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); //接收浏览器传入的数据 String ename = req.getParameter("ename"); String job = req.getParameter("job"); String sal = req.getParameter("sal"); //增加保存这些数据 Emp e = new Emp(); e.setEname(ename); e.setJob(job); if(sal != null && !sal.equals("")) { e.setSal(new Double(sal)); } new EmpDao().save(e); //重定向到查询页面: //建议浏览器自己去访问查询页面 //当前:/EmpManager/addEmp //目标:/EmpManager/findEmp res.sendRedirect("findEmp"); } }
package web; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dao.EmpDao; import entity.Emp; public class FindEmpServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //查询所有的员工 EmpDao dao = new EmpDao(); List<Emp> list = dao.findAll(); //向浏览器输出响应信息 res.setContentType( "text/html;charset=utf-8"); PrintWriter out = res.getWriter(); //当前:/EmpManager/findEmp //目标:/EmpManager/add_emp.html out.println("<a href='add_emp.html'>增加</a>"); out.println("<table border='1' cellspacing='0' width='30%'>"); out.println(" <tr>"); out.println(" <td>编号</td>"); out.println(" <td>姓名</td>"); out.println(" <td>职位</td>"); out.println(" <td>薪资</td>"); out.println(" </tr>"); if(list != null) { for(Emp e : list) { out.println("<tr>"); out.println(" <td>"+e.getEmpno()+"</td>"); out.println(" <td>"+e.getEname()+"</td>"); out.println(" <td>"+e.getJob()+"</td>"); out.println(" <td>"+e.getSal()+"</td>"); out.println("</tr>"); } } out.println("</table>"); out.close(); } }
这个代码把上面两个方法合并到这里了,并用 *.do 来访问;
package web; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dao.EmpDao; import entity.Emp; /** * 路径规范: * 查询员工: /findEmp.do * 增加员工: /addEmp.do */ public class MainServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{ //获取请求路径 String p = req.getServletPath(); //根据规范处理路径 if("/findEmp.do".equals(p)) { findEmp(req,res); } else if("/addEmp.do".equals(p)) { addEmp(req,res); } else { throw new RuntimeException("查无此页"); } } protected void findEmp( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //查询所有的员工 EmpDao dao = new EmpDao(); List<Emp> list = dao.findAll(); //向浏览器输出响应信息 res.setContentType( "text/html;charset=utf-8"); PrintWriter out = res.getWriter(); //当前:/EmpManager/findEmp //目标:/EmpManager/add_emp.html out.println("<a href='add_emp.html'>增加</a>"); out.println("<table border='1' cellspacing='0' width='30%'>"); out.println(" <tr>"); out.println(" <td>编号</td>"); out.println(" <td>姓名</td>"); out.println(" <td>职位</td>"); out.println(" <td>薪资</td>"); out.println(" </tr>"); if(list != null) { for(Emp e : list) { out.println("<tr>"); out.println(" <td>"+e.getEmpno()+"</td>"); out.println(" <td>"+e.getEname()+"</td>"); out.println(" <td>"+e.getJob()+"</td>"); out.println(" <td>"+e.getSal()+"</td>"); out.println("</tr>"); } } out.println("</table>"); out.close(); } protected void addEmp( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); //接收浏览器传入的数据 String ename = req.getParameter("ename"); String job = req.getParameter("job"); String sal = req.getParameter("sal"); //增加保存这些数据 Emp e = new Emp(); e.setEname(ename); e.setJob(job); if(sal != null && !sal.equals("")) { e.setSal(new Double(sal)); } new EmpDao().save(e); //重定向到查询页面: //建议浏览器自己去访问查询页面 //当前:/EmpManager/addEmp.do //目标:/EmpManager/findEmp.do res.sendRedirect("findEmp.do"); } }
package web; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dao.EmpDao; import entity.Emp; /** * 路径规范: * 查询员工: /findEmp.do * 增加员工: /addEmp.do */ public class MainServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException{ //获取请求路径 String p = req.getServletPath(); //根据规范处理路径 if("/findEmp.do".equals(p)) { findEmp(req,res); } else if("/addEmp.do".equals(p)) { addEmp(req,res); } else { throw new RuntimeException("查无此页"); } } protected void findEmp( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //查询所有的员工 EmpDao dao = new EmpDao(); List<Emp> list = dao.findAll(); //向浏览器输出响应信息 res.setContentType( "text/html;charset=utf-8"); PrintWriter out = res.getWriter(); //当前:/EmpManager/findEmp //目标:/EmpManager/add_emp.html out.println("<a href='add_emp.html'>增加</a>"); out.println("<table border='1' cellspacing='0' width='30%'>"); out.println(" <tr>"); out.println(" <td>编号</td>"); out.println(" <td>姓名</td>"); out.println(" <td>职位</td>"); out.println(" <td>薪资</td>"); out.println(" </tr>"); if(list != null) { for(Emp e : list) { out.println("<tr>"); out.println(" <td>"+e.getEmpno()+"</td>"); out.println(" <td>"+e.getEname()+"</td>"); out.println(" <td>"+e.getJob()+"</td>"); out.println(" <td>"+e.getSal()+"</td>"); out.println("</tr>"); } } out.println("</table>"); out.close(); } protected void addEmp( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); //接收浏览器传入的数据 String ename = req.getParameter("ename"); String job = req.getParameter("job"); String sal = req.getParameter("sal"); //增加保存这些数据 Emp e = new Emp(); e.setEname(ename); e.setJob(job); if(sal != null && !sal.equals("")) { e.setSal(new Double(sal)); } new EmpDao().save(e); //重定向到查询页面: //建议浏览器自己去访问查询页面 //当前:/EmpManager/addEmp.do //目标:/EmpManager/findEmp.do res.sendRedirect("findEmp.do"); } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>增加员工</title> </head> <body> <!-- 当前:/EmpManager/add_emp.html 目标:/EmpManager/addEmp.do --> <form action="addEmp.do" method="post"> <p> 姓名:<input type="text" name="ename"/> </p> <p> 职位:<input type="text" name="job"/> </p> <p> 薪资:<input type="text" name="sal"/> </p> <p><input type="submit" value="保存"/></p> </form> </body> </html>
案例二:演示路径输出,访问项目的三种方式:
package web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AbcServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //获取访问路径 System.out.println( req.getContextPath()); System.out.println( req.getServletPath()); System.out.println( req.getRequestURI()); System.out.println( req.getRequestURL()); //若没有设置响应信息的话,服务器 //依然会向浏览器做出默认的响应, //但响应的内容为空. } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>servlet3</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>abc</servlet-name> <servlet-class>web.AbcServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>abc</servlet-name> <!-- 1.精确匹配 --> <!-- <url-pattern>/abc</url-pattern> --> <!-- 2.通配符 --> <!-- <url-pattern>/*</url-pattern> --> <!-- 3.后缀(不要写/) --> <url-pattern>*.duang</url-pattern> </servlet-mapping> </web-app>
案例三:演示Servlet程序调度规则:
package web; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DemoServlet extends HttpServlet { //DemoServlet,实例化 == new 调用一次 public DemoServlet() { System.out.println("实例化DemoServlet"); } //init,初始化 爷爷的方法 调用一次 @Override public void init(ServletConfig config) throws ServletException { super.init(config); System.out.println("初始化DemoServlet"); } //service,执行程序逻辑 访问多少次,调用多少次 @Override protected void service( HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { System.out.println("调用DemoServlet"); } //destroy,关闭Servlet 调用一次 @Override public void destroy() { super.destroy(); System.out.println("销毁DemoServlet"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>servlet4</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>demo</servlet-name> <servlet-class>web.DemoServlet</servlet-class> <!-- 这里可以控制,启动时第1个加载此Servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>demo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping> </web-app>
后一天讲的内容:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>servlet4</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>demo</servlet-name> <servlet-class>web.DemoServlet</servlet-class> <!-- 启动时第2个加载此Servlet --> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>demo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping> <servlet> <servlet-name>login</servlet-name> <servlet-class>web.LoginServlet</servlet-class> <init-param> <param-name>maxonline</param-name> <param-value>3000</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <servlet> <servlet-name>findDept</servlet-name> <servlet-class>web.FindDeptServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>findDept</servlet-name> <url-pattern>/findDept</url-pattern> </servlet-mapping> <servlet> <servlet-name>findEmp</servlet-name> <servlet-class>web.FindEmpServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>findEmp</servlet-name> <url-pattern>/findEmp</url-pattern> </servlet-mapping> <!-- 给所有的Servlet预置参数,该参数由context 对象自动读取. Tomcat启动时首先就会创建context对象,它会 给每个项目创建唯一的一个context. context内部有静态块,首次调用时就执行, 此块内加载了web.xml中的参数. --> <context-param> <param-name>size</param-name> <param-value>10</param-value> </context-param> <servlet> <servlet-name>init</servlet-name> <servlet-class>web.InitServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>up</servlet-name> <servlet-class>web.UpServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>up</servlet-name> <url-pattern>/up</url-pattern> </servlet-mapping> </web-app>
ServletConfig,一对一 和 init 调用时机讲解:
package web; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { /** * 1.config对象由tomcat创建及传入 * * LoginServlet servlet = new LoginServlet(); * //Tomcat每创建一个Servlet后,就会立刻给它 * //创建一个config对象. * //config内有静态块,调用时加载参数(首次访问) * ServletConfig cfg = new ServletConfig(); * //通过init方法传入此config对象 * servlet.init(cfg); * //父类的init(cfg)方法内部调用了init() * * 2.使用config不是必须要重写init(), * 若在service()中调用config,通过父类 * 提供的getServletCofig()就可以获取它. * 该方法返回的config就是init()所传入 * 的那个config. * * */ @Override public void init(ServletConfig config) throws ServletException { System.out.println("调用有参的init()"); super.init(config); } @Override public void init() throws ServletException { System.out.println("调用无参的init()"); super.init(); } @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //获取在线人数最大值 ServletConfig cfg = getServletConfig(); String maxonline = cfg.getInitParameter("maxonline"); System.out.println(maxonline); } }
ServletContext,一对多:
package web; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FindDeptServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //获取每页显示的行数 ServletContext ctx = getServletContext(); String size = ctx.getInitParameter("size"); System.out.println(size); //统计流量 Integer count = (Integer) ctx.getAttribute("count"); ctx.setAttribute("count", ++count); System.out.println("流量:"+count); } }
package web; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FindEmpServlet extends HttpServlet { @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { //获取每页显示的行数 ServletContext ctx = getServletContext(); String size = ctx.getInitParameter("size"); System.out.println(size); //统计流量 Integer count = (Integer) ctx.getAttribute("count"); ctx.setAttribute("count", ++count); System.out.println("流量:"+count); } }
这个文件只是初始化变量,还是访问上面这两个文件,进行测试程序,
package web; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; /** * 该Servlet不用来处理任何请求,只是用来 * 在Tomcat启动时初始化一些数据而已. * 在你工作时会发现很多项目中都有1个/多个 * 这样的Servlet. */ public class InitServlet extends HttpServlet { @Override public void init() throws ServletException { super.init(); //将流量初始化为0 ServletContext ctx = getServletContext(); ctx.setAttribute("count", 0); } }
演示线程安全,增加 synchronized(this) 保证线程安全:
package web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UpServlet extends HttpServlet { private Double salary = 3000.0; @Override protected void service( HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { synchronized(this) { //模拟涨工资 salary += 100; //模拟网络延迟 try { Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } res.setContentType( "text/html;charset=utf-8"); PrintWriter out = res.getWriter(); out.println(salary); out.close(); } } }