servlet03 重定向、访问路径及其配置方式、处理多个请求、servlet对象的生命周期、乱码问题
1 重定向
程序必须满足低耦合、高类聚的原则;所以在一个servlet组件中不能去调用另外一个servlet组件,这样会造成高耦合现象;利用重定向可以很好的解决这种现象
1.1 重定向经典用途
百度搜索就是很经典的重定向:例如,在百度中搜索“大足石刻”,会弹出有关大足石刻官网的词条信息,当你点击大足石刻官网的那个词条信息时并不是直接前往大足石刻官网,而是先向百度的服务器发出请求,百度的服务器在接收到请求后就知道你是向要访问大足石刻的官网,所以就重定向到大足石刻官网;然后你才能访问到大足石刻的服务器
1.2 重定向在项目中的应用

1 package web; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.text.SimpleDateFormat; 6 import java.util.Date; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 public class DateServlet extends HttpServlet { 14 15 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 16 Date date = new Date(); 17 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 18 String now = sdf.format(date); 19 20 resp.setContentType("text/html;charset=utf-8"); 21 PrintWriter out = resp.getWriter(); 22 out.println("<p>三少,你好;现在的日期是:"+now+"</p>"); 23 out.close(); 24 } 25 26 }

1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <display-name>dateServlet</display-name> 4 <welcome-file-list> 5 <welcome-file>index.html</welcome-file> 6 <welcome-file>index.htm</welcome-file> 7 <welcome-file>index.jsp</welcome-file> 8 <welcome-file>default.html</welcome-file> 9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 13 <servlet> 14 <servlet-name>date</servlet-name> 15 <servlet-class>web.DateServlet</servlet-class> 16 </servlet> 17 <servlet-mapping> 18 <servlet-name>date</servlet-name> 19 <url-pattern>/date</url-pattern> 20 </servlet-mapping> 21 22 <servlet> 23 <servlet-name>login</servlet-name> 24 <servlet-class>web.LoginServlet</servlet-class> 25 </servlet> 26 <servlet-mapping> 27 <servlet-name>login</servlet-name> 28 <url-pattern>/login.do</url-pattern> 29 </servlet-mapping> 30 31 </web-app>

1 package web; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 public class LoginServlet extends HttpServlet { 12 13 @Override 14 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 15 16 resp.setContentType("text/html;charset=utf-8"); 17 PrintWriter out = resp.getWriter(); 18 out.println("hello"); 19 resp.sendRedirect("date"); // 重定向到另外一个servlet组件 20 out.close(); 21 } 22 23 }
2 访问路径
静态资源(html/img)的访问路径:就是Tomcat中的存放路径
动态资源(servlet)的访问路径:就是在配置文件中配置的网名
2.1 访问路径(即:动态资源的网名)的配置方式
精确匹配(/path):只有 /path 这一个名字可以访问此 Servlet (此 Servlet 只能处理一个请求)
通配符(/*):所有的名字都可以访问此 Servlet (此 Servlet 能处理一切请求)
后缀(*.path):所有以 path 为后缀的名字都可以访问此 Servlet (此 Servlet 能处理很多请求)
2.2 通过request对象获取访问路径
System.out.println(req.getContextPath()); // 返回项目路径 /Path
System.out.println(req.getServletPath()); // 返回网名路径 /path
System.out.println(req.getRequestURI()); // 返回网名的绝对路径 /Path/path
System.out.println(req.getRequestURL()); // 返回网名的完整路径 http://localhost:8080/Path/path
2.3 URI 和 URL 的深层理解
将URI理解为资源的名称(三少/老三/少爷/王杨帅) -->> 是绝对路径
将URL理解为资源的真名(王杨帅) -->> 是完整路径
> URI包含了URL
3 使用一个servlet组件处理多个请求
原理:在一个继承了HttpServlet的类中写多个service方法,每个service方法处理一个请求;把其中一个service方法用来做请求分发(即:根据相应的请求处理调用相应的service方法)

1 package web; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 import dao.EmpDao; 13 import dao.EmpDaoImpl; 14 import entity.Emp; 15 16 /** 17 * 路径规范 18 * 1 查询员工: /findEmp.do 19 * 2 增加员工:/addEmp.do 20 * 21 * 利用一个 servlet 来管理 22 * @author soft01 23 * 24 */ 25 public class MainServlet extends HttpServlet { 26 27 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 28 29 // 获取请求路径 30 String p = req.getServletPath(); 31 32 // 判并处理 33 if("/findEmp.do".equals(p)) { 34 findEmpService(req, resp); 35 } else if("/addEmp.do".equals(p)) { 36 addEmpService(req, resp); 37 } else { 38 throw new RuntimeException("查无此页"); 39 } 40 } 41 42 protected void findEmpService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { 43 44 // 1 无 45 // 2 查询所有员工 46 EmpDao dao = new EmpDaoImpl(); 47 List<Emp> list = dao.findAll(); 48 49 // 3 返回响应信息 50 res.setContentType("text/html;charset=utf-8"); 51 PrintWriter out = res.getWriter(); 52 53 // 当前路径:/EempManager/findEmp.do 54 // 目标路径:/EmpManager/html/add_emp.html 55 out.println("<a href='html/add_emp.html'>增加</a>"); 56 out.println("<table border='1' cellspacing='0' width='40%'>"); 57 out.println(" <tr>"); 58 out.println(" <td>编号</td>"); 59 out.println(" <td>姓名</td>"); 60 out.println(" <td>职位</td>"); 61 out.println(" <td>薪资</td>"); 62 out.println(" </tr>"); 63 for(Emp e : list) { 64 out.println("<tr>"); 65 out.println("<td>"+e.getEmpno()+"</td>"); 66 out.println("<td>"+e.getEname()+"</td>"); 67 out.println("<td>"+e.getJob()+"</td>"); 68 out.println("<td>"+e.getSal()+"</td>"); 69 out.println("</tr>"); 70 } 71 out.println("</table>"); 72 out.println("EmpManager02"); 73 out.println("你选择了跳转到findEmp的Servlet"); 74 out.close(); 75 } 76 77 protected void addEmpService(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { 78 req.setCharacterEncoding("utf-8"); 79 80 // 1 接受参数 (从页面获取的都是字符串) 81 String ename = req.getParameter("ename"); 82 String job = req.getParameter("job"); 83 String sal = req.getParameter("sal"); 84 85 // 2 处理业务 86 Emp e = new Emp(); 87 e.setEname(ename); 88 e.setJob(job); 89 e.setSal(new Double(sal)); 90 EmpDao dao = new EmpDaoImpl(); 91 dao.save(e); 92 93 // 3 返回响应 94 /* 95 res.setContentType("text/html;charset=utf-8"); 96 PrintWriter out = res.getWriter(); 97 out.println("<p>增加成功</p>"); 98 out.close(); 99 */ 100 101 // 重定向到查询功能 102 // 建议客户自己去访问查询功能 103 // 当前路径:/EempManager/addEmp.do 104 // 目标路径:/EmpManager/findEmp.do 105 res.sendRedirect("findEmp.do"); 106 } 107 108 }
4 servlet对象的生命周期
创建 -> 初始化 -> 调用service方法 -> 销毁
默认情况下 servlet 实例对象是在首次访问 servlet 的时候创建;但是也可以配置成启动Tomcat的时候就创建,而且还可以指定创建次序

1 package web; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 12 * 默认情况下 servlet 实例对象是在首次访问 servlet 的时候创建;但是也可以配置成启动Tomcat的时候就创建,而且还可以指定创建次序 13 * > 怎么配置见web.xml 14 * @author Administrator 15 * 16 */ 17 public class LifeServlet extends HttpServlet { 18 19 20 public LifeServlet() { 21 System.out.println("1 创建LifeServlet"); 22 } 23 24 public void destroy() { 25 super.destroy(); 26 System.out.println("4 销毁LifeServlet"); // 只有通过 右键单击 Servers 选择 stop 选项 才会有效果 27 } 28 29 public void init(ServletConfig config) throws ServletException { 30 super.init(config); 31 System.out.println("2 初始化LifeServlet"); 32 } 33 34 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 35 System.out.println("3 调用service()方法"); 36 } 37 38 }

1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <display-name>LifeServlet</display-name> 4 <welcome-file-list> 5 <welcome-file>index.html</welcome-file> 6 <welcome-file>index.htm</welcome-file> 7 <welcome-file>index.jsp</welcome-file> 8 <welcome-file>default.html</welcome-file> 9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 13 <servlet> 14 <servlet-name>life</servlet-name> 15 <servlet-class>web.LifeServlet</servlet-class> 16 17 <!-- 告诉tomcat在启动时第2个创建该Servlet --> 18 <load-on-startup>2</load-on-startup> 19 </servlet> 20 <servlet-mapping> 21 <servlet-name>life</servlet-name> 22 <url-pattern>/life</url-pattern> 23 </servlet-mapping> 24 25 <servlet> 26 <servlet-name>login</servlet-name> 27 <servlet-class>web.LoginServlet</servlet-class> 28 29 <!-- 给Servlet预置参数,参数会被config加载 --> 30 <init-param> 31 <param-name>maxOnline</param-name> 32 <param-value>2000</param-value> 33 </init-param> 34 </servlet> 35 <servlet-mapping> 36 <servlet-name>login</servlet-name> 37 <url-pattern>/login</url-pattern> 38 </servlet-mapping> 39 40 <servlet> 41 <servlet-name>findDept</servlet-name> 42 <servlet-class>web.FindDeptServlet</servlet-class> 43 </servlet> 44 <servlet-mapping> 45 <servlet-name>findDept</servlet-name> 46 <url-pattern>/findDept</url-pattern> 47 </servlet-mapping> 48 49 <servlet> 50 <servlet-name>findEmp</servlet-name> 51 <servlet-class>web.FindEmpServlet</servlet-class> 52 </servlet> 53 <servlet-mapping> 54 <servlet-name>findEmp</servlet-name> 55 <url-pattern>/findEmp</url-pattern> 56 </servlet-mapping> 57 58 <!-- 给所有的Servlet预置共性的参数,该参数由context在服务器启动时加载 --> 59 <context-param> 60 <param-name>size</param-name> 61 <param-value>10</param-value> 62 </context-param> 63 64 <servlet> 65 <servlet-name>init</servlet-name> 66 <servlet-class>web.InitServlet</servlet-class> 67 <load-on-startup>1</load-on-startup> 68 </servlet> 69 <!-- 无 service,故不用配置这个部分 70 <servlet-mapping> 71 <servlet-name>init</servlet-name> 72 <url-pattern>/init</url-pattern> 73 </servlet-mapping> 74 --> 75 76 <servlet> 77 <servlet-name>up</servlet-name> 78 <servlet-class>web.UpSalaryServlet</servlet-class> 79 </servlet> 80 <servlet-mapping> 81 <servlet-name>up</servlet-name> 82 <url-pattern>/up</url-pattern> 83 </servlet-mapping> 84 </web-app>
5 乱码问题
导致乱码的原因都是因为浏览器和服务器的编码方式不一致造成的
5.1 服务器产生乱码问题
当浏览器发出的是get请求时
在配置文件中配置服务器的解码方式为utf-8即可
当浏览器发出的是post请求时
在程序中设定服务器的解码方式
resp.setCharacterEncoding("utf-8");
5.2 浏览器产生乱码问题
在服务器中配置消息头的相关内容,通知浏览器利用utf-8进行解码
resp.setContentType("text/html;charset=utf-8"); // 指定发送给浏览器的文件格式以及文件编码
5.3 注意
浏览器出IE外都是使用的utf-8格式进行编码(IE用的是gbk格式进行编码)
服务器都是利用ISO-8859-1格式进行编码
只要保证浏览器和服务器的编码格式一致就可以有效的避免乱码问题