【Servlet-request对象、response对象、请求转发与重定向区别、servlet生命周期、servlet线程安全问题】

本文详细讲解了Servlet中的request对象、response对象操作,区分请求转发与重定向,剖析Servlet生命周期,并探讨了线程安全问题及其解决方案。涵盖了get/post请求的区别、数据传输、地址栏变化、资源访问权限以及如何确保多线程环境下的数据一致性。

Servlet-request对象、response对象、请求转发与重定向区别、servlet生命周期、servlet线程安全问题


一、request请求对象

1.客户端通过get或者post方式提交的数据,都保存在request对象中

2.get与post区别

1)get请求(对应doGet方法)

		·get提交的数据会放在URL之后,以?分割,参数之间以&相连
		·get方式明文传递,数据量小,不安全
		·效率高,是浏览器默认的请求方式

2)post请求(对应doPost方法)

		·post方法是把提交的数据放在HTTP包的body中
		·密文传递数据,数据量大,安全
		·效率相对没有get高

3.request常用方法

		·String getParameter(String name)                                根据表单提交的name名称获取对应的value值
		·void setCharacterEncoding(String charset)					指定每个请求的编码格式
		·HttpSession getSession()                     							获取session对象
		·String getContextPath()													获取上下文路径
		·Cookies[] getCookies()													获取cookies数组
		·String getAttribute(String s)											获取request域中传输的数据(s为name名称)
		·void setAttribute(String s,Object o)                                向request域中传输数据
		·RequestDispatcher getRequestDispatcher(String s)	获取请求分配器(s为请求转发的路径)
		·String getHeader(String s)												获取请求头
		·Enumration<String> getHeaderNames
		·String getMethod()     														获取提交方法

4.request请求转发

1)转发是在服务器内部,请求本项目中其他资源(包含WEB-INF中的资源),通过request域对象共享数据,来共同完成客户的一次请求,地址栏不发生变化
2)代码实现方法
			request.setAttribute(String key,Object value);      //将数据存储到request作用域中(一次请求中有效,一次请求可以经过多次转发)
			request.getRequestDispatcher("/目标资源路径").forward(request,response);
			//用于服务器内部跳转
			Object value =request.getAttribute(key);
			//用于在一次请求的任意位置,获取request域中的共享数据

二、response响应对象

1.用于响应客户请求,并向客户端输出信息

2.response常用方法

		·	void setHeader(String name,String value)									设置响应头信息
		· void setStatus(int i)																		设置响应状态
		· void setContentType(String s)														设置响应文件类型、响应编码格式
		·void setCharacterEncoding(String s)												设置服务端响应内容编码格式
		·PrintWriter getWriter()																		获取字符输出流
		·ServletOutputStream getOutputStream()										获取字节输出流

		解释说明:
		response.setCharacterEncoding("utf-8");    //设置服务端响应的编码格式
		response.setHeader("content-type","text/html;charset=utf-8");   
		//设置客户端响应内容的头内容的文件类型及编码格式

		同时设置服务端编码格式和客户端响应的文件类型与编码格式(推荐使用)
		response.setContentType("text/html;charset=utf-8")
@WebServlet( "/SecondServlet")
public class SecondServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	response.setContentType("text/html;charset=utf-8")
    	//注意在获得输出流之前设置
        PrintWriter writer = response.getWriter();
        writer.println("register success");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

3.response重定向

1)重定向是作用在客户端,客户端发送请求给服务器后,服务器响应给客户端一个新的请求地址,客户端重新按新地址发起请求(注意:地址栏有明显变化;可以访问不同网站,不同项目中的资源文件(WEB-INF中的资源文件除外)

2)代码实现方法

		方式一(推荐使用):
		response.sendRedirect("目标URI");
		URI:(uniform resource identifier)统一资源标识符,用于在服务器中定位一个资源的位置(web项目上下文路径+具体资源路径)
		方式二:
		response.setHeader("location","目标URI");
		response.setStatus(302);

3)response请求转发数据传输

		response没有作用域,而且两次request请求中的数据无法共享,因此数据传输通过URI的拼接来进行
		例:
		response.sendRedirect("目标URI?username = tom");
		String username =request.getParameter("username");
		注意:由于request.getParameter(String name)只能接收String类型的参数,因此这种方法只能明文传递String类型数据

三、请求转发与重定向区别

1.数据传输

	request请求转发是服务器内部行为,一次请求多次转发,可以共享request作用域中的任意类型数据(基本数据类型、数组、集合等)
	response重定向是客户端行为,客户端发起请求后,服务器响应新的地址,客户端重新按新的地址发起请求,两次请求不能共享request域中的数据(只在一次请求中有效),并且response本身没有作用域,只能通过在URI后拼接进行明文String类型的数据传输(不安全)

2.地址栏变化

	request请求转发是一次请求,多次转发,地址栏没有变化
	response重定向是发起两次请求,地址栏有明显变化

3.可访问的资源文件

	request请求转发只能访问同一个web项目下的资源文件(包含WEB-INF中的),不能跨项目访问
	response重定向可以跨网站,跨项目访问资源文件(WEB-INF中资源文件除外)

四、Servlet生命周期

1.实例化

	默认收到请求时创建实例,也可以通过<load-on-startup>设置在容器启动之后立即创建实例
	注意:单例模式,只执行一次

2.初始化

		在初始化阶段,调用init(ServletConfig config);
		注意:只执行一次

3.服务

		当收到客户端请求时,容器会将请求与响应对象以参数的形势转给Servlet
		注意:此方法执行多次

4.销毁

		当容器停止或者重启时,会调用destory方法销毁servlet对象

五、Servlet线程安全问题

1.Servlet在收到访问请求后,会创建实例,而Tomcat容器是允许多个线程并发访问同一个servlet,如果在方法中对成员变量做修改,会产生线程安全问题

2.如何确保线程安全问题

1)synchronized将存在线程安全问题的代码放到同步代码块中(即将原子操作上锁),效率低

2)实现SingleThreadModel接口后,每个线程都会创建servlet实例,每个客户端请求就不存在共享资源问题,但响应客户端请求的效率太低,资源浪费大,所以已淘汰

3)尽可能使用局部变量(推荐使用)


与poppy一起学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值