Response响应内容
方法 | 形式 |
---|---|
getWriter() | 以字符流的方式向客户端响应 |
getOutputStream | 以字节流的方式响应客户端内容 |
- sendError()返回错误
从Servlet中获得请求信息
1、获得request中携带的请求报文信息
HttpServletRequest req=((HttpServletRequest)servletRequest);
//获得ServletContext对象 Servlet的上下文环境,该对象中主要存放一些和容器通信的方法
ServletContext application=req.getServletContext;
//通过ServletContext可以获得项目所在的绝对路径或者tomcat热加载的项目位置
String path =application.getRealPath("/");
//通过ServletContext可以加载资源 getResourceAsStream()
InputStream is=application.getResourceAsStream("/image/1.jgp");
//请求转发
RequestDispatcher rsd=req.getResquestDispatcher("aaa.html");
res.forward(ServletResquest,ServletResponse);
//请求url的完整地址 http://localhost:8080/xxx/xxx.html
StringBuffer resquestURL=req.getResquestURL();
//请求的URI
String resquestURI=req.getResquestURI();
//get方式提交上来?后边的参数,post无效
String queryString=req.getQueryString();
//获得Content-Type头的内容,没有返回null
String contentType=req,getContentType();
//获得请求行的第一部分:请求的方法 GET POST PUT DELETE
String method=req.getMethod();
//<URL-PATTERN>
String serletpath=req.getServletPath();
//协议、版本
String protocol=req.getProtocol();
Enumeration<String> headerNames=req.getHeaderNames();
while(headerNames.hasMoreElements()){
String header=headerNames.nextElement();
String value=req.getHeader();
}
//获得请求中的Content-Length 消息体参数的长度 get无效
int cl = req.getContentLength();
req.setCharacterEncoding("UTF-8");
/获得参数
String uname = req.getParameter("username");
String[] eats = req.getParameterValues("eat");
/* InputStream is1 = req.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is1));
String str = br.readLine();
System.out.println(str);
*/
ServletContext的理解
- ServletContext一般翻译为上下文环境,是Servlet和容器通讯的方法的集合
- 获得ServletContext的方式
- request.getServletContext();
- ServletConfig.getServletContext();
- ServletContext的常见方法
- getRealPath()
- getResourceAsStream()
- getAttribute()/setAttribute()
- addServlet/addFilter/addListener
三大范围
- HttpServletResquest
- HttpSession
- ServletContext
- 以上三个方法都含有getAttribute和setAttribute方法,都可以存放数据
关于请求中的Content-Type[客户端 浏览器]
- form表单中有一个默认的属性
enctype=application/x-www-form-urlencoded
,作用是告诉浏览器在封装的请求头中添加Content-Type:application/x-www-form-urlencode
,该头的作用是把消息体中的参数组装成key=value&key1=value1…格式的字符串发送到服务器[如果有文件,装的是文件的名字,而不是文件本身] - enctype的属性值可以改成:multipart/form-data;boundary=—sadasdas;意思是吧请求中的参数以boundary指定的分隔符分割成多部份,组装发送服务器,不再以key=value的&key1=value1的方式发送
- 当客户端发送请求时,Content-Type请求头还可以是application/json,作用就是告诉浏览器在封装的请求头中添加
Content-Type:application/json"
,表示把参数组装成json格式传送到服务器
服务器处理不同的Content-Type的参数
- Tomcat只能自动解析application/x-www-form-urlencoded格式的参数:即ket=value
- 如果是multipart/form-data格式的参数,我们需要
首先从请求头中获得Content-Type(req.getContentType()),从而能够过得boundary(分隔符),然后getInputStream()把数据获得,在使用分隔符把每一部分数据分割解析
以上工作可以使用第三方插件(commons-fileload),我们从第三方插件中获得【普通参数+文件参数】
- 如果是application/json我们通过getInputStream读取即可,然后通过第三方插件(解析JSON的组件)把JSON格式的字符串转换成某些Java对象
Servlet生命周期
- 默认当请求到达服务器时才会创建Servlet对象,并且初始化执行init()操作。不管请求多少次,服务器只会创建一个Servlet对象,以多线程的方式响应客户端的请求。
- 如果注册Servlet时使用了
<load-on-startup>
,则tomcat会在启动时立即创建Servlet对象并初始化操作,不用等到发请求的时候 - 当请求被tomcat接收后,tomcat首先会判断本次请求是静态资源还是动态资源,如果是静态资源,则交给DefaultServlet处理,如果是servlet/jsp则会根据web.xml中的配置,寻找合适的servlet进行处理
- 找到Servlet类之后,首先从内存中存放Servlet对象的集合中查看是否有对应的Servlet对象,如果有则调用原来servlet的service方法,如果没有则创建新的Servlet对象,然后再把这个Servlet对象放到存放Servlet对象的集合中[Servlet是单例的]
- 创建完Servlet对象后,执行init()方法,执行初始化操作[加载资源、读取配置]
- init()方法是Servlet在容器调用service方法处理请求之前调用的,主要用来
- 传入ServletConfig对象;该对象主要存放一些Servlet的初始化信息、参数
- 做一些预处理:加载资源、读取配置的操作
Servlet中的核心API
javax.servlet.Servlet:
- 定义了所有Servlet都要实现的方法,即每一个Servlet都要实现该接口
- 方法:
- init(ServletConfig)
- service()
- destory()
- getServletConfig()
- getServletInfo()
- Servlet类就是运行在服务器上的小Java程序。能够接收和处理来自客户端的请求。通常是HTTP协议
- 该接口定义了初识化Servlet、服务请求、从服务器删除Servlet的方法,这个方法被称作生命周期方法,并按照以下顺序调用:
- Servlet被构造,然后调用init方法初识化。
- 所有来自客户端的请求都交给service处理
- 请求处理完毕后,做一些销毁资源、关闭资源的操作从destory,然后Servlet对象就等待GC回收
javax.servlet.ServletConfig:
- ServletConfig对象是被Servlet容器创建的,在Servlet初始化阶段以init()参数的形式传递给Servlet。
- 我们可以在初始化的时候通过ServletConfig获得一些Servlet的启动信息
- Servlet和ServletConfig是一一对应的,一个Serlvlet一定有一个对应ServletConfig对象。相当于我们每个人都有一个身份证,身份证上存放着我们的初始化信息
- 方法列表:
- getInitParameter(String) :根据名字获取初始化参数
- getInitParameterNames():获得所有的初始化参数的名字
- getServletContent():获得ServletContent对象
- getServletName():获得servlet的名字
@Override //初始化方法测试 public void init(ServletConfig config) throws ServletException { System.out.println("FirstServlet初始化。。init.."); Enumeration<String> initParameterNames = config.getInitParameterNames(); while(initParameterNames.hasMoreElements()){ //初始化参数名 String paramName = initParameterNames.nextElement(); String paramValue = config.getInitParameter(paramName); System.out.println(paramName+"\t"+paramValue); } ServletContext application = config.getServletContext(); //<servlet-name> String servletName = config.getServletName(); }
javax.servlet.ServletContext:
- 获得ServletContext的方式
- request.getServletContext();
- ServletConfig.getServletContext();
- ServletContext的常见方法
- getRealPath()
- getResourceAsStream()
- getAttribute()/setAttribute()
- addServlet/addFilter/addListener
- 一个ServletContext对象对应多个Servlet,所以我们获得ServletContext,该对象被容器创建
核心API的构造、实现、调用
API名字 | 构造者new | 调用者 | 实现者 |
---|---|---|---|
Servlet | 容器 | 容器 | 我们 |
ServletConfig | 容器 | 我们 | 容器 |
ServletContext | 容器 | 我们 | 容器 |
ServletRequest | 容器 | 我们 | 容器 |
ServletResponse | 容器 | 我们 | 容器 |
ResquestDispatcher | 容器 | 我们 | 容器 |
HttpSession | 容器 | 我们 | 容器 |
从Servlet接口到HttpServlet类
- 官方提供了GenericServlet,该类中实现了init(ServletConfig)
- setServletConfig()
- 初始化分发给init()处理,如果有必要我们重写无参的init()初始化
- service方法是抽象的
- 在HttpServlet中,继承了GenericServlet,重写service(ServletRequest,ServletResponse),强转类型位Http版本,分发给protected service(HttpRequest,HttpResponse),在该方法中根据请求提交的方法,分发给相应的doxxx方法,我们重写doxxx
- 当我们需要实现Servlet类时,继承HttpServlet即可