Servlet特性及路径处理

一. GET和POST使用场景(建议)

  • 查询数据是用GET,因为通常查询条件较小
  • 提交数据(表单)时用POST,因为通常提交的数据较多

二. 增加员工案例

当前页面是查询页面:/EmpMangager/findEmp
FindEmpServlet.java

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 org.apache.jasper.tagplugins.jstl.core.Out;

import dao.EmpDao;
import dao.EmpDaoImpl;
import entity.emp;

public class FindEmpServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		//1.接收参数(没有)
		//2.处理业务(查询)
		EmpDao dao =new EmpDaoImpl();//实例化dao
		List list=dao.findAll();
		//3.输出响应(表格)
		res.setContentType("text/html;charset=utf-8");
		PrintWriter out = res.getWriter();
		out.println("增加");//超链接路径是目标路径的相对路径
		out.println(" ");
		out.println("	");
		out.println("		");
		out.println("		");
		out.println("		");
		out.println("		");
		out.println("	");
		if(list!=null){
			for (emp e : list) {
				out.println("");
				out.println("	");
				out.println("	");
				out.println("	");
				out.println("	");
				out.println("");
			}
		}
		out.println("
编号姓名职位月薪
"+e.getEmpno()+""+e.getEname()+""+e.getJob()+""+e.getSal()+"
"); out.close(); } }

web.xml

findEmp
  Web.FindEmpServlet
  
  
  findEmp
  /findEmp
  

目标是增加页面:/EmpManager/add_emp.html
相对路径是:add_emp.html

add_emp.html




Insert title here



姓名:

职位:

月薪:

点击保存后调用访问/addEmp
AddEmpServlet.java

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;

import org.apache.jasper.tagplugins.jstl.core.Out;

import dao.EmpDao;
import dao.EmpDaoImpl;
import entity.emp;

public class AddEmpServlet extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		//1.接收参数
		 req.setCharacterEncoding("utf-8");//处理POST方式中文乱码
         String ename = req.getParameter("ename");
         String job = req.getParameter("job");
         String sal= req.getParameter("sal");
		//2.处理业务
		emp e = new emp();
		e.setEname(ename);
	 	e.setJob(job);
		if(sal!=null&&!sal.equals("")){
			e.setSal(new Double(sal));//自动装箱
		}
		EmpDao dao=new EmpDaoImpl();
		dao.save(e);
	3.输出响应
		res.setContentType("text/html;charset=utf-8");
		PrintWriter out =res.getWriter();
		out.println("

保存成功

"); out.close(); } }

保存成功后重定向到查询页面

//重定向到查询页面,就是建议浏览器访问查询页面
		//当前路径:/EmpManager/addEmp
		//目标路径:/EmpMaager/findEmp			
		res.sendRedirect("findEmp");入代码片

三. 重定向

1. 经典的使用场景

  • 解决两个网站之间的跳转问题

2. 增加的场景

  • 解决一个网站内两个独立组件之间的跳转(302代码)
  • 一般增加、修改、删除后重定向到查询

四. 路径

1.什么是路径

Servlet特性及路径处理_第1张图片

建议: 将访问路径理解为一个资源的名字

2.URI和URL的区别

1)狭义的理解

  • 只在Java中理解URI和URL
  • URI:绝对路径
  • URL:完整路径

从表面上看URI包含URL

2) 广义的理解(*)

  • 在任意的WEB项目中理解URI和URL
  • URI:资源的名称(可以有多个)。
  • URL:资源的真名(只能有一个)。

URI包含URL

3. 如何配置Servlet访问路径即web.xml文件

1)精确匹配

  • 举例:/abc
  • 只有/abc才能访问此Servlet
  • 此Servlet只能处理这一个要求

适合小规模项目

2)通配符

  • 举例:/*
  • 所有的路径都能访问此Servlet
  • 此Servlet能处理所有请求

适合一个项目只写一个Servlet

3) 后缀

  • 举例:*.hi
  • 所有以hi为后缀的请求都能访问此Servlet
  • 此Servlet能处理多个请求

适合一个项目写少量的几个Servlet

4. 使用一个Servlet处理多个请求

Servlet特性及路径处理_第2张图片

五. Servlet生命周期

Servlet特性及路径处理_第3张图片

六. ServletConfig和ServletContext

1.他们的作用Servlet特性及路径处理_第4张图片

2. 它们的区别

1)config

  • 和Servlet是一一对应关系
  • Tomcat在初始化每一个Servlet前都会创建一个Config
  • 调用XXServlet.init()前给他创建一个config
  • 如果想给某个Servlet预制数据,使用config

2) context

  • 和Servlets是一对多关系
  • Tomcat在启动时就创建唯一的一个context
  • 所有的Servlet都可以共享这个对象中的数据
  • 如果想给多个Servlet预制数据,使用context

3. 它们的应用

1)config

  • 需求:假设要开发一个网页游戏,当用户超出最大在线人数时要排队。登陆时判断是否已到达最大人数。
  • 登陆:LoginServlet
  • 最大人数:maxOnline,可以配置
  • 该参数只需要LoginServlet使用,用config读取即可
    web.xml设置参数

    login
    web.LoginServlet
    //设置参数maxOnline
      maxOnline
      3000
    
  
  
    login
    /login
  

LoginServlet.java

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 {
	/*Tomcat创建servlet逻辑:
     * LoginServlet s= new LoginServlet();
     * ServletConfig c= new ServletConfig
     * c.加载数据();从web.xml中加载数据
     * s.init(c)*/
	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		String maxOnline = config.getInitParameter("maxOnline");//读取设定的参数
		System.out.println(maxOnline);
		}
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		ServletConfig cfg=getServletConfig();//init()传入的那个config
		String maxOnline=cfg.getInitParameter("maxOnline");
		System.out.println(maxOnline);
		System.out.println("正在登录...");
	}
    
	

}

2)context

  • 软件内有很多查询功能,都带有分页功能
  • 每页显示的行数size是常量,并且可配置
  • 该数据再多个查询功能之间共用,用context读取
    web.xml 设置参数

  
  size
  20
  

FindEmpServlet.java

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 {
		/*
		 * tomcat启动时就会创建唯一的context,并且会调用它的方法加载web.xml中的公用参数
		 * context是全局的,任何servlet都可以使用
		 */
		ServletContext ctx = getServletContext();
		String size = ctx.getInitParameter("size");
		System.out.println(size);//size在多个servlet中都要使用
		System.out.println("分页查询员工数据");
	}

}


FindDeptServlet.java

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 {
        /*tomcat启动时就会创建唯一的context,并且会调用它的方法加载web.xml中的公用参数
         * context是全局的,任何servlet都可以使用
         * */
		ServletContext ctx = getServletContext();
		String size = ctx.getInitParameter("size");
		System.out.println(size);
		System.out.println("分页查询部门数据");
	}

}

4.context的特殊用法

  • 前提:之前使用config和context读取的是常量
  • 而context还有能力读写变量
  • 用该对象读写的变量是可以被所有servlet共用
  • 使用setAttribute/getAttribute读取变量
  • 案例:开发流量统计功能,无论访问哪个功能,流量+1
  • 由于流量是变量,并且在多功能之间共用,所以用context
    设置变量初始值 InitServlet.java
package web;

import java.util.concurrent.CountDownLatch;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class InitServlet extends HttpServlet {

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		//tomcat启动时会优先创建context然后再创建servlet
		ServletContext context=getServletContext();
		context.setAttribute("count", 0);
	}
/*该Servlet不负责处理具体的业务,只用来在tomcat启动时初始化数据。
 * 一般web项目都有1-2个这样的servlet*/
	
}

读取变量

Integer count = (Integer) ctx.getAttribute("count");
		ctx.setAttribute("count", ++count);
		System.out.println(count);

5. 总结

  • 当需要给Servlet预置参数时使用这样的对象
  • 若参数只给一个Servlet使用,用config
  • 若参数给多个Servlet共用,用context

七. Servlet层次结构

1.整体结构

Servlet特性及路径处理_第5张图片

2. HttpServletServlet特性及路径处理_第6张图片

Servlet特性及路径处理_第7张图片
Servlet特性及路径处理_第8张图片
Servlet特性及路径处理_第9张图片

八. Servlet线程安全问题

1. 同时修改局部变量

  • 局部变量存在栈内
  • 每个线程有自己的栈帧

此时没有线程问题

2. 同时修改成员变量

  • 成员变量存在堆内
  • 所有线程共享这样的数据

此时存在线程安全问题

3. 解决方案

  • 加锁
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 {
	double salary = 2000.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();
		}
		
	}

}

你可能感兴趣的:(Servlet特性及路径处理)