概念:
是一个java的接口是以多线程的方式运行在服务端的小程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。
模型:
Servlet是不依赖平台的的java类,被编译为中间字节码,可被动态装载运行于支持java的web服务器上。这里说的容器,有时也称它为servlet引擎,提供Servlet功能的web服务器扩展,servelt通过一种由servlet容器实现的request/response范式(paradigm)与web客户机交互。
servlet容器:
servlet容器是web服务器或应用服务器的一部分,它们提供处理request并发送response的网络服务。servlet容器包含并管理着servlet对象的生命周期。
执行流程:
请求流程
1.客户端发出一个请求URL,URL中的一部分是Servlet的名字。
2.Web服务器转发请求到Servlet引擎,Servlet class的实例在其里面。
3.Servlet引擎调用Servlet的方法。
4.在HttpServlet中,Servlet的service方法最终将调用doPost()方法或者doGet()方法。
响应流程
1.Servlet将动态响应请求,并把结果发到Web服务器。
2.Web服务器发送动态生成的响应给客户端。
servlet生命周期:
1.客户端第一次访问servlet的url路径时 由服务器创建servlet对象并调用init()进行初始化
2.调用对应的service方法处理客户端请求 httpServlet中调用doget()和dopost()
3.当服务器关闭时销毁servlet对象并调用destroy方法进行清理
代码实现:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获得请求的编码
req.setCharacterEncoding("utf-8");
String encoding = req.getCharacterEncoding();
//2.获得客户端发送请求的部分路径 /projectName/url...
String uri = req.getRequestURI();
//3.获得客户端发送请求的完整路径
StringBuffer url = req.getRequestURL();
//4.获得客户端的ip地址
String ip = req.getRemoteAddr();
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("请求编码:"+encoding+"<br/>");
out.print("请求uri:"+uri+"<br/>");
out.print("请求url:"+url+"<br/>");
out.print("请求的客户端ip:"+ip+"<br/>");
// doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得客户端提交的参数
//设置请求的内容的编码格式
req.setCharacterEncoding("UTF-8");
//1.根据参数的名称获得参数的值
//请求的参数中该参数名字不存在时 获得是null
String username = req.getParameter("username");
String sex = req.getParameter("sex");
String judge = req.getParameter("judge");
String city = req.getParameter("city");
//2.根据参数的名称获得参数的值 返回的 是字符串数组 用于名称相同 值不同的参数 的获取
String[] password = req.getParameterValues("password");
String[] hobby = req.getParameterValues("hobby");
//3.获得所有的参数 返回的是一个map对象
Map<String, String[]> parameterMap = req.getParameterMap();
for(Entry<String, String[]> entry:parameterMap.entrySet()) {
System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));
}
System.out.println("-----------");
//4.获得所有的参数名称
Enumeration<String> names = req.getParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String[] values = req.getParameterValues(name);
System.out.println(name+":"+Arrays.toString(values));
}
//将从客户端获取的值 响应到客户端
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("恭喜你注册成功!");
out.print("用户名:"+username+"<br/>");
out.print("密码:"+Arrays.toString(password)+"<br/>");
out.print("性别:"+sex+"<br/>");
out.print("自我评价:"+judge+"<br/>");
out.print("所在城市:"+city+"<br/>");
out.print("爱好:"+Arrays.toString(hobby)+"<br/>");
}
}
作用域:
三大作用域(用于服务器端应用程序之间传值)
1.request作用域 (HttpServletRequest)
request.setAttribute(String name,Object value);//往作用域中存放值
request.getAttribute(String name);//根据属性的名字获得值
一次请求有效
2.session作用域(HttpSession)
session.setAttribute(String name,Object value);//往作用域中存放值
session.getAttribute(String name);
一次会话有效 同一个浏览器窗口不关闭情况下 都是属于同一个会话
有效期(默认是30分钟) 从最后一次访问当前项目开始计时
session的有效期过了之后 session对象才会被销毁
关闭窗口后,只是客户端拿不到session对象了,而服务端的session对象还是存在
3.application作用域(ServletContext)
全局作用域,整个应用期间都有效,除非服务器关闭
两种跳转方式对比:
1.服务端跳转 request.getRequestDispatcher(“url”).forword(request,response):
服务器端来完成页面的请求
一次请求,客户端地址栏不会改变的
跳转路径:
只能跳转当前工程中的目录,包括/WEB-INF/目录下的文件
相对路径:相对于当前servlet的请求路径
绝对路径:绝对于工程的根路径
request作用域有效
2.客户端跳转 response.sendRedirect(“url”);
通过客户端来完成页面的第二次请求
第一次请求到服务端后,客户端得到一个302的响应状态,并且获得一个请求路径,由客户端
来完成后面的请求
两次请求,客户端地址栏会发生改变,显示为第二次请求的路径
跳转路径:
除了跳转当前工程中的路径 之外,还可以跳转其他工程中的目录
但是不能访问/WEB-INF/目录下的文件
相对路径:相对于当前的servlet的访问路径
绝对路径:绝对于服务器的根路径
request作用域无效
线程安全问题
servlet不是线程安全的,servlet是单实例多线程运行的