Servlet要点、请求与响应

一: Servlet要点

01.Servlet规范和搭建JavaWeb项目

什么是Service:

		Service是JavaEE的组件,service是一个程序类,要求必须实现javax.service.Service接口.
		
		也是JavaEE中的规范.服务器其实是Service的实现,

搭建标准的JavaWeb的项目结构:

		1.创建一个java项目:HelloServletWeb:
	
		2.在HelloServletWeb中创建一个文件夹webapp,表示web项目的根;

		3.在webAPP中创建WEB-INF文件夹,

		4.WEB-INF中创建文件夹:lib,classes

		5.WEB-INF中去Tomcat根/conf拷贝web.xml文件,只需要保留根元素.

		6.把当前项目的classpath路径改成webapp/WEB-INF下的classes中.

02.第一个Servlet的程序

Service的第一个程序编写步骤:

			1):拷贝Tomcat根/lib/servlet-api.jar到项目的WEB-INF/lib目录中,并做build path.
			
			2):编写Servlet程序,使之实现javax.servlet.Servlet接口,并覆盖接口中的方法.
				public class HelloServlet implement javax.servlet.Servilet(...实现方法...)
				
			3):发现方法中的参数出现arg0,arg1的情况是因为没有关联Servlet的源代码.
				是否关联源代码和程序最终的运行没有关系,只是在开发阶段参数美观,可阅读源代码.
				
			4):在service(ServletRequest req, ServletResponse res)方法,打印一句话.
			   引导:此时HelloServlet类,和Tomcat一点关系都没有:我们需要告诉Tomcat来帮我们管理HelloServlet类,
			   (Tomcat是Servlet的容器,会负责Servlet对象的声明)所以,得以配置的形式,告诉Tomcat来帮我们管理自定义的Servlet类.
			   
			5):Servlet配置:在web.xml文件中的配置,切记<url-pattern>/hello</url-pattern>中的hello要加"/"
			
			6):部署项目并访问:server.xml中:<Context docBase="D:\Java EE\Servlet\webapp" path="day3">
			
			访问:http://ip:port/contextPath/资源名
    			http://localhost:80/day3/hello

03.Servlet的生命周期方法

Servlet的生命周期:创建对象,初始化操作,运行操作,销毁操作.

javax.servlet.Servlet接口中的方法:

		String getServletInfo():获取Servlet的信息(Servlet的作者,版本,版权相关).

		ServletConfig getServletConfig();获取Servlet的配置信息对象.

生命周期方法:WEB的生命周期中(Tomcat启动-->Tomcat关闭),Servlet是单例的.
	
		构造器:在服务端程序第一次被请求的时候,调用,只被调用一次.

		void init(ServletConfig config);在构造器执行完毕之后,调用init方法,也只会执行一次.

		void service(ServletRequest req, ServletResponse resp):每一次请求都会执行该方法.

		void destroy();正常关闭Tomcat才会执行(该方法不一定会被执行,我们没有必要在其中编写扫尾的操作).

总结:   构造器--->init方法---> {servlet方法}循环 ---->destory方法

注意: 
	 1):Servlet类的构造器必须使用public修饰.

	 2):Servlet类必须是无参数构造器.

	原因:底层创建Servlet对象:class.newInstance()方式.--->公共的无参数构造器.

	总结:保证Servlet必须有一个公共的无参数构造器,方便Tomcat底层创建Servlet的对象.

04.Servlet的请求流程-图片版
在这里插入图片描述

05.Servlet的请求流程-文字版

	1:浏览器先发送请求:http://localhost:80/day3/hello
	
	2:DNS解析域名(忽略)

	3:Tomcat解析请求:/day3/hello.  上下文路径:/day3   资源的名称/hello

	4:解析Tomcat根/conf/server.xml文件,获取其中所有的<Context/>元素,并找到path属性为/day3的元素.

		<Content docBase="D:\Java EE\Servlet\webapp" path="day3"/>.
	
		再读取该<Content/>元素,再获取docBase属性值,该属性值就是当前访问的WEB项目的根路径.

	5:从该web的根路径/WEB-INF下找到web.xml文件.

	6:读取web.xml文件,获取所有的<url-patten>元素,并判断哪一个<url-pattern>的文本内容为:/hello.
	
		找不到:404错误.    找到:GOTO  7.
	
	7:通过/hello ,找到当前Servlet的全限定名:com._520it._01_hello.HelloServlet
	
	8:从Servlet的实例缓存池中去获取com._520it._01_hello.HelloServlet对应的对象

	 Map<String,Servlet> cache = ....;

	 Servlet obj = cache.get("com._520it._01_hello.HelloServlet");

	 if(obj==null){
		  //第一次请求:GOTO 9
	 }else{
		  //非第一次请求:GOTO 12
	 }
	
	9:使用反射创建Servlet对象.
	
	 Servlet obj = Class.forName("com._520it._01_hello.HelloServlet").newInstance();

	10:把创建的Servlet对象,存储到Servlet实例缓存池中,供下一次请求使用.

	 cache.put("com._520it._01_hello.HelloServlet",obj);

	11:容器创建ServletConfig对象,并调用init方法,来完成初始化操作.

	 obj.init(config);

	12:容器创建ServletRequest和ServletResponse对象,并调用service方法.
		
	 obj.service(req,resp);
	
	13:在service方法中对,当前请求的客户端做响应

06.ServletConfig接口获取初始化参数

ServletConfig接口:表示Servlet的信息配置对象(web.xml中,当前Servlet的配置信息).

其中方法:

	String getServletName();获取当前Servlet的名字,<servlet-name>元素的文本内容.

	ServletContext getServletContext();获取当前Servlet的指定的参数名获取初始化参数值.

	Enumeration<String> getInitParameterName();获取当前Servlet的所有初始化参数的名字.

07.Servlet继承体深入讲解系列

public class Servlet1 extends MyHttpServlet{

	private static final long serialVersionUID = 1L;
	
	public void service(HttpServletRequest req, HttpServletResponse resp) {
		
		super.service(req, resp);
		System.out.println("utf");
	}
}
public class MyHttpServlet extends MyGenericServlet{
	private static final long serialVersionUID = 1L;
	//只能处理一般的请求
	public void service(ServletRequest req, ServletResponse resp){
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		service(request,response);//获取请求方式,GET/POST
	}
	
	//专门处理Http的请求
	public void service(HttpServletRequest req, HttpServletResponse resp){
		String method = req.getMethod();//获取请求方式,GET/POST
		if("GET".equals(method)){
			doGet(req,resp);
		}else{
			doPost(req,resp);
		}
	}
	//专门用于处理POST请求
	private void doPost(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("Servlet1.doPost()");
	}
	//专门用于处理GET请求
	private void doGet(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("Servlet1.doGet()");
	}
}

abstract public class MyGenericServlet implements Serializable,Servlet,ServletConfig{

	private static final long serialVersionUID = 1L;
	private ServletConfig config = null;
	
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
		this.init();
	}
	
	//专门暴露给子类,让子类编写自身的初始化代码
	public void init(){
		//NO OP
	}
	@Override
	abstract public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException;
	//把ServletConfig对象暴露给子类访问
	public ServletConfig getServletConfig() {
		return this.config;
	}

	public String getServletInfo() {
		return null;
	}

	public void destroy() {
		
	}

	public String getServletName() {
		return config.getServletName();
	}

	public ServletContext getServletContext() {
		return config.getServletContext();
	}

	public String getInitParameter(String name) {
		return config.getInitParameter(name);
	}

	public Enumeration<String> getInitParameterNames() {
		return config.getInitParameterNames();
	}
}

8.Servlet继承体系总结和开发Servlet

前端web实际开发的时候只需继承HttpServlet类,调用service()方法,并记得删除方法中的super.service(req,resp);

在这里插入图片描述

9.HttpServletRequest接口和常用方法

	String getInitParameter(String name):获取初始化参数,初始化参数是开发人员设置的

	String getParameter(String name):获取用户输入的参数,参数是不同的用户输入的(通过表单) 

	常用方法:

	01.String getMethod():返回请求方式:GET/POST  只有表单中method=post才是post

	02.String getRequestURI();返回请求行中的资源名字部分:/test/index.html
	
	03.StringBuffer getRequestURL():返回浏览器地址栏中所有的信息

	04.String getContextPath():返回当前项目的上下文路径(<Context/>元素的path属性值.)

	05.String getRemoteAddr():返回发出请求的客户机的IP地址

	06.String getHeader(String name):返回指定名称的请求头的值

	获取请求参数的方法:

	01.String getParameter(String name):返回指定参数名字的值

	02.String[] getParameterValues(String name):返回指定名字参数的多个参数值.

	03.Enumeration<String> getParameterNames()返回所有的参数名的Enumeration对象

	04.Map<String,String[]> getParameterMap():返回所有的参数和值所组成的Map对象.

10.处理请求中文乱码问题

	在Tomcat中,对于POSTGET请求,都默认才有ISO-8859-1的编码方式.ISO-8850-1不支持中文,所以乱码.

	解决方案:
	
		1:按照ISO-8859-1把乱码恢复成二进制形式

    	  byte[] data = username.getBytes("ISO-8859-1");

		2:再把二进制形式的数据使用UTF-8重新编写

		  String username = new String(data,"UTF-8");
	
		一个参数需要使用两行代码来转码,如果有N个参数,需要转N次代码重复.

	解决方案:
	
		针对于POST的请求方式: req.setCharacterEncoding("UTF-8");
		
							注意:1.只对POST有效. 2:必须放在获取任意参数之前.
							
		针对于GET的请求方式:修改Tomcat中的server.xml配置文件,GET方式的默认编码.
		
							URIEncoding="ISO-8859-1"改为"UTF-8"

11.HttpServletResponse接口和常用方法

	ServletResponse接口:响应对象.封装了获取响应信息的方法.

	HttpServletResponse接口:ServletResponse的子接口,可以处理HTTP响应的方法.

	常用方法:

	    	01.OutputStream getOutputStream();获取字节输出流对象.   输出图片等

     		   注意:可以一起输出多个getOutputStream(),但是不可以跟getWriter()一起使用:

			02.PrintWriter getWriter():获取字符流输出对象      输出英文或者中文等

			03.设置输出数据的MIME类型:resp.setContentType("text/html");

			04.设置输出数据的编码方式:resp.setCharacterEncoding("UTF-8");

			可以将上述3,4两行代码合并成一行代码:resp.setContentType("text/html;charset=UTF-8");

			注意:必须先设置MIME类型和编码,再获取输出流,否则没有效果.

12.网页版的简易计算器

静态网页版

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Insert title here</title>
</head>
<body>
	<form action='/cal' method='post'>
			<input type='number' name='num1' />
			<select name='op'>
				<option>+</option>
				<option>-</option>
				<option>*</option>
				<option>/</option>
			</select>
			<input type='number' name='num2' />
			<input type='submit' value=' = '/>	
			<input type='text' value='' disabled />
	</form>
</body>
</html>

动态的Servlet网页

public class CalServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		//================================
		//2:接受表单中的数据
		String snum1 = req.getParameter("num1");
		String op = req.getParameter("op");
		String snum2 = req.getParameter("num2");
		String result = "";
		if(haslength(snum1) && haslength(snum2)){
			Integer num1 = Integer.valueOf(snum1);
			Integer num2 = Integer.valueOf(snum2);
			if("+".equals(op)){
				result = num1+num2+"";
			}else if("-".equals(op)){
				result = num1*num2+"";
			}
		}
		//================================
		//1:输出一个计算器的界面
		out.print("<form action='/cal' method='post'>");
		out.print("<input type='number' name='num1' value='"+snum1+"'/>");
		out.print("<select name='op'>");
		out.print("<option>+</option>");
		out.print("<option>-</option>");
		out.print("<option>*</option>");
		out.print("<option>/</option>");
		out.print("</select>");
		out.print("<input type='number' name='num2' value='"+snum2+"'/>");
		out.print("<input type='submit' value=' = ' />");
		out.print("<input type='text' value='"+result+"' disabled/>");
	}
	private boolean haslength(String str){
		return str!=null && !"".equals(str.trim());
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值