Servlet、Request、Response

Servlet

//是一个接口、规范,其相应的类由Tomcat服务器实现
//GenericServlet  HttpServlet 是其实现类

Servlet的执行过程

1.	在浏览器上输入http://localhost/firstservlet/first
2.	首先被监听80端口号的connector HTTP 1.1 接收,并生成request对象和一个空的response对象,之后将请求转发给Engine处理。
3. 	engine根据host选择虚拟主机host
4. 	在host节点下去搜寻Context节点,应用名
5.	去web.xml中搜索/first,通过url-pattern找到servlet-name,找到相应的class文件,加载
6. 	检查是否有servlet实例化对象,若没有就通过反射来创建实例化对象,并执行init方法初始化
7.	直接调用servlet的service方法并将创建的request和response对象传进去
8.	执行service方法
9.	WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

实现Servlet的方式

//继承GenelicServlet
	实现其抽象方法server
	修改web.xml文件,添加
	<servlet>
		<servlet-name/class> 
	</servlet>
	<servlet-mapping>
		<servlet-name>
		<url-pattern>
	</servlet-mapping>
//继承HttpServlet
	重写其doGet/doPost方法
	修改web.xml文件
//使用注解
	在idea的新建中的最后面找到creat new servlet
	出现:@WebServlet(name="ThirdServlet",url-pattern="/third")
	Name对应web.xml中的servlet-name节点,urlPatterns对应url-pattern节点。
	可以进一步精简为@WebServlet("/third")

idea与Tomcat的关联

	idea里面的目录是开发目录,他将tomcat里的conf复制了一份,不会对tomcat产生影响
	最终部署目录,在最终部署应用的时候会将开发目录的web目录下的所有文件都复制到部署目录中
	若开发目录的web下未设置classes文件夹,他也会自动在部署目录生成一个文件夹保存.class文件

servlet的生命周期

	正常情况下,servlet在第一次访问的时候被tomcat创建
	可以通过设置Load-on-startup的参数为一个非负数,让servlet在项目加载的时候自动创建。
	Load-on-startup默认-1,表示初次访问的时候才会加载。数字大小表示加载的先后顺序,越小则越先加载。
	
	在web.xml中创建
		<servlet>
			<load-on-startup>1</load-on-startup>
		</servlet>

###url映射
	一个servlet可以配置多个url,
	多个servlet不可以配置同一个url

url冲突匹配

	url-pattern只能以/或*开头
	/开头的优先级高于*开头的
	匹配程度越高优先级越高
	存在/ *  jsp html 都无法访问,被/ *拦截了
	存在/,不存在/ *时,可以访问jsp无法访问html//因为系统会自动执行自己定义的/,将系统默认的/覆盖
	访问静态资源的时候,有servlet参与
	//在开发过程中,不要设置/*和/的url-pattern。
	/的优先级最低,当匹配不到资源的时候访问/,/一般定义的是一些404页面之类的处理

ServletConfig

	可以在init方法中获取该servlet定义的一些初始化参数

ServletContext对象

获取EE项目的文件路径
	getServletContext().getRealPath("1.html")//真实路径
	//获取ee项目的文件路径
		在哪个目录下调用jvm,就相对的是哪个路径
		用Main方法调用jvm

共享对象
		
		setAttribute()   getAttribute()
		removeAttribute()
		//可以被同应用下的不同servlet访问
		ServletContext servletContext = getServletContext();//活得context对象
		servletContext.setAttribute("name","zhangsan");//设置context的值
		String name = (String)servletContext.getAttribute("name");//获得值
		servletContext.removeAttribute("name");//删除name属性
		
		//使用共享对象来统计网页访问量
		@WebServlet("/history")
		public class HistoryCountServlet extends HttpServlet {
			protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

			}

			protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				ServletContext servletContext = getServletContext();
				//首先应该想一下用什么来存
				//首先是set还是get
				Integer count = null;
				synchronized (this){
					count = (Integer) servletContext.getAttribute("count");
					//条件判断 空指针异常
					//count.intValue() 这步才会空指针异常
					if(count == null){
						//没有代表第一次访问
						servletContext.setAttribute("count",new Integer(1));
					}else{
						servletContext.setAttribute("count",count + 1);
					}
				}

				count = (Integer) servletContext.getAttribute("count");
				response.getWriter().println("history count :" + count);
			}
		}
	
获取全局性的初始化参数
	
		//所有的servlet均可以获取到该初始化参数
		在web.xml中定义
		<context-param>
			<param-name>enconding</param-name>
			<param-value>utf-8</param-value>
		</context-param>
		
		ServletContext servletContext = getServletContext();
		String name = servletContext.getInitParameter("name");
		
		//ServletConfig初始化参数的标签叫init-param,
			这个标签是存在于servlet内部的,
			所以仅当前servlet可以获取到该初始化参数。

request


request获取客户机信息api

	getQueryString 方法返回请求行中的参数部分,不能返回正文的参数
	getRequestURL//方法返回客户端发出请求时的完整URL。
	getRequestURI//方法返回请求行中的资源名部分。
	getRemoteAddr//方法返回发出请求的客户机的IP地址
	getRemoteHost//方法返回发出请求的客户机的完整主机名
	getRemotePort//方法返回客户机所使用的网络端口号
	getLocalAddr//方法返回WEB服务器的IP地址。
	getLocalName//方法返回WEB服务器的主机名
	getMethod//得到客户机请求方式

获取客户机请求头

	getHeader(name)//name是请求头前面的key,可以是任意的
	getHeaderNames//返回一个包含请求头的key的一个数组
		Enumeration<String> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()){
			System.out.println(headerNames.nextElement());
		}

获取客户机提交的数据
	
	getParameter(name)//获取名为name的属性的值
	getParameterValues(String name)//获取某个属性的多个值
	getParameterNames()//获取所有提交数据的属性名,返回一个数组
	
	
	将客户端发送的数据存到bean中
		//利用反射
		
		工具包//beanUtils
		使用:
			Map<String, String[]> parameterMap = request.getParameterMap();
			BeanUtils.populate(user, parameterMap);

中文乱码问题

	post: request.setCharacterEncoding("utf-8");//设置服务器的解码方式
	get: 若浏览器提交的是utf-8 编码的就不会乱码

地址路径写法

	分为:以/开头和不以/开头两种
	对以/开头来说,要看执行主体是服务器还是浏览器
		若是浏览器,因为浏览器不知道应用名所以,/应用名/资源名
		若是服务器,/资源名

请求转发和包含

	//一种在服务器内部的资源跳转方式
	1.步骤:
        //通过request对象获取请求转发器对象:
		RequestDispatcher dispatcher = request.getRequestDispatcher(String path);
        //使用RequestDispatcher对象来进行转发:
		dispatcher.forward(request,response);
		//包含
		dispatcher.include(request,response);


    2.特点:
        浏览器地址栏路径不发生变化
        只能转发到当前服务器内部资源中。
        转发是一次请求
		源组件和目标组件共享同一个request对象和response对象。
	3.包含特点
		源组件与被包含的目标组件的输出数据都会被添加到响应结果中。
		在目标组件中对响应状态代码或者响应头所做的修改都会被忽略。

	4.源组件与目标组件
		转发:(源组件)留头(响应头)不留体(响应体)。
			//源组件做了初步处理之后,将请求转发给目标组件,
			//之后源组件对于响应正文的数据不再参与进来,全权由目标组件来完成。但是它可以写入响应头信息。
		包含:(源组件)留头(响应头)也留体(响应体)。
			//主要用在一个页面引用另外一个或者多个页面。
	
	5.用途
		转发:一般用在servlet组件完成相应的逻辑之后,跳转至相关的页面,
			  转发的源组件一般仅会处理一些响应头,响应正文由目标组件来提供,执行的侧重点在目标组件。
		包含:一般用在页面和页面的相互引用方面,比如一个页面可以在底部引入一个声明页。
			  这个时候就可以用包含。源组件均可响应体以及响应头。执行的侧重点仍然在源组件。
			  
	6.转发包含两个组件的执行过程
		执行到forward/include行代码,执行完毕,
		跳转至目标组件执行,目标组件代码执行完之后,
		再次回到源组件继续执行forward/include行后面的代码。		  

request域

	Context域范围:整个web应用下的资源都可以访问到
	Request域范围:针对同一个request对象内有效,所有共享同一个request对象的组件,都可以共享request域。
				   转发的源组件和目标组件共享request域

	方法:
		void setAttribute(String name,Object obj):存储数据
		Object getAttitude(String name):通过键获取值
		void removeAttribute(String name):通过键移除键值对		  

Response对象

功能:设置响应消息

结构
		响应行:版本协议  状态码  描述原因
		响应头
		空行
		响应体
设置响应行

	1.格式:
		HTTP/1.1 200 ok
	2.设置状态码:
		response.setStatus(int sc);
		
设置响应头:
	setHeader(String name, String value) 
		
设置响应体:
	使用步骤:
		1.获取输出流
		
			字符输出流:PrintWriter getWriter()

			字节输出流:ServletOutputStream getOutputStream()

		2.使用输出流,将数据输出到客户端浏览器

输出中文乱码问题

	1.
	浏览器端,在window中文简体下,默认是GBK编码格式
	服务器端,可以设置服务器的编码为response.setCharacterEncoding("GBK");来解决
		//但这种方法不具有普遍性
	2.	
	//告诉浏览器服务器采用什么编码方式
	response.setContentType("text/html;charset=utf-8");
	respons.setHeader("content-type","text/html;charset=utf-8");
		两层意思:
			规范服务端的数据采用utf-8 进行编码
			告诉浏览器我的编码方式是什么
			
	3.jsp方式

字节流传输文件和中文

	//字符输出流:默认编码是GBK
	
	response.setContentType("text/html;charset=utf-8");
	String realPath = getServletContext().getRealPath("2.png");
	FileInputStream fin = new FileInputStream(new File(realPath));
	ServletOutputStream out = respons.getOutputStream();
	byte[] bytes = new byte[1024];
	int len=0;
	while((len=fin.read(bytes))!=-1){
		out.write(bytes,0,len);
		out.write("中文".getBytes(utf-8));
	}
	fin.close();

设置响应头定时刷新

	response.setHeader("refresh","2;url=path");//可不写url表示当前页面自动刷新
	
	//特点
		地址栏发生变化
		可以访问其他站点(服务器)的资源
		是两次请求。不能使用request对象来共享数据

重定向

	1.
	response.sendRedirect(request.getContextPath()+"/应用名/资源名");
	
	2.设置响应码,加location头
	response.setStatus(302);
	response.setHeader("Location",request.getContextPath()+"/应用名/资源名");
	
	3.重定向的特点:redirect
		地址栏发生变化
		重定向可以访问其他站点(服务器)的资源
		重定向是两次请求。不能使用request对象来共享数据

获取路径

	request.getServletContext().getRealPath(path);//获取Web项目的全路径
	request.getServletPath() //得到当前页面所在目录下全名称
	request.getRequestURI()//得到资源的相对地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值