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一起学习