10、HttpServlet原理

1、为了保证前后端请求一致,在每一个Servlet类都需要编写之前的代码,怎样能封装一下,以后在每一个具体的Servlet类中不写这样的代码了,但是还是能够达到同样的效果 ?

中间添加一个父类就可以了,不让LoginServlet直接继承GenericServlet,去继承中间的父类,父类里封装好保证前后端请求一致的代码。

  • 现在存在一个问题。我们通过这个父类可以知道请求是GET或者POST,那怎么让LoginServlet这种实际业务类根据请求方式做出相应的反应呢?
    比如登录发GET,我们要报错,是POST,我们要实现正确的功能。

正确代码如下:HtttpServlet

public class HtttpServlet extends GenericServlet {

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		
		//将ServletRequest,ServletResponse向下转型成带有Http的接口类型
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)res;
		
		//为什么这里要service()方法?
		this.service(request, response);
	}
	
	public void service(HttpServletRequest request,HttpServletResponse response) 
			throws ServletException, IOException {
		
		//从浏览器中获取请求方式
		String method = request.getMethod();
		
		if ("GET".equals(method)) {
			this.doGet(request,response);
		} else if("POST".equals(method)) {
			this.doPost(request,response);
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException,IOException {
		
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		//前台报出错误
		out.print("405-应当发送GET请求");
		//后台报出错误
		throw new RuntimeException("405-应当发送GET请求");
		
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException,IOException {
		
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		//前台报出错误
		out.print("405-应当发送POST请求");
		//后台报出错误
		throw new RuntimeException("405-应当发送POST请求");
	}

}
为什么那里service()方法里要有个this.servies()方法?
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
	
	//将ServletRequest,ServletResponse向下转型成带有Http的接口类型
	HttpServletRequest request = (HttpServletRequest)req;
	HttpServletResponse response = (HttpServletResponse)res;
	
	//为什么这里要service()方法?
	this.service(request, response);
}

这个思想和前面所讲的this.init()方法是一样的。HtttpServlet继承GenericServlet,覆写了service()方法。ServletRequest req, ServletResponse res为了识别请求方式就一定要向下转型,这是在service()方法中实现的,那子类LoginServlet继承HtttpServlet覆写servic()方法就得加一句super.service();,这多麻烦。

所以在service()方法里调用一个普通方法,取名也叫service(),让子类去覆写这个普通方法。这样就父类中的代码运行到了,子类覆写的代码也运行到了。

上面那个根据请求方式做出相应动作是这样完成的

核心思想还是和上一个问题一样,子类覆写父类的方法,没有加super.xxx();子类就会覆盖父类的方法。

在普通service()方法上做判断:

public void service(HttpServletRequest request,HttpServletResponse response) 
		throws ServletException, IOException {
	
	//从浏览器中获取请求方式
	String method = request.getMethod();
	
	if ("GET".equals(method)) {
		this.doGet(request,response);
	} else if("POST".equals(method)) {
		this.doPost(request,response);
	}
}

普通方法里同样的配方,再来调用两个普通方法doGet(),doPost()父类HtttpServlet这两个方法里面写前后端报错信息,子类LoginServlet,根据自己想要的方式,选择一个覆写真实的业务。

  • 注意:因为我们的业务其实是在Servlet的service()方法里面执行,所以真正在实现业务的是HtttpServlet类,我们只是在HtttpServlet的service()方法开了一个口子,把业务可以写到别的地方去,但最终还是回到了HtttpServlet的service()方法。

作为登录业务,我希望用POST请求方式,那我就覆写doPOST()方法,里面写正常的业务。这样如果请求是GET,先会一路执行到HtttpServlet的doGet()方法,里面有报错信息,然后发现子类LoginServlet没有覆写doGet()方法,就执行父类HtttpServlet中的doGet()方法了,输出报错信息。

这种设计,就保证前后端请求一致了。不一致就报错,一致就正常执行业务。

public void doPost(HttpServletRequest request, HttpServletResponse response) 
		throws ServletException,IOException {
	
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	
	//前台报出错误
	out.print("405-应当发送GET请求");
	//后台报出错误
	throw new RuntimeException("405-应当发送GET请求");
	
}

public void doGet(HttpServletRequest request, HttpServletResponse response) 
		throws ServletException,IOException {
	
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	
	//前台报出错误
	out.print("405-应当发送POST请求");
	//后台报出错误
	throw new RuntimeException("405-应当发送POST请求");
}

LoginServlet.java :

public class LoginServlet extends HtttpServlet {

	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//super.doGet(request, response); 这一句写上去就前功尽弃了
		response.getWriter().print("login...");
	}

}

其实我们手写的父类HtttpServlet,sun公司已经写好了,叫HttpServlet

总结:

  • 编写一个Servlet类应当继承javax.servlet.http.HttpServlet,get请求请重写doGet方法,post请求请重写doPost方法

  • doPost/doGet方法可以等同看做main方法

  • 当浏览器发送的请求方式和后台的处理方式不同的话,会出现一个错误, 代号: 405

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值