java_web学习笔记之Servlet

时间:2023-02-24 19:12:43
Servlet
Server applet 的缩写 ==>  服务器段的一个小程序. 也就是运行在tomcat上的程序. 由此有的时候 也管服务器叫做servlet容器.
Servlet也是servlet技术中的三大组件之一.

servlet  
filter  过滤器
listener 监听器

1.如何写一个servlet?
    <span style="white-space:pre"></span>*实现javax.servlet.Servlet 接口.
<span style="white-space: pre;"></span>*继承javax.servlet.GenericServlet 抽象类
*继承javax.servlet.http.HTTPServlet 抽象类
2.Servlet中的生命周期方法.
*void init(ServletConfig config)
*void service(ServletRequest request,ServletResponse response)
*void destory()
3.Servlet中的其他方法
*ServletConfig  getServletConfig();
*StringgetServletInfo();
4.ServletConfig对象 干吗用的?范围?
<servlet>
<servlet-name>AServlet</servlet-name>
<servlet-class>xxx.xxx.xx</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>tom</param-value>
</init-param>
</servlet>

*String getServletName
*String getInitParameter(String name) 根据参数的键获得值
*Enumeration getInitParameterNames() 获得所有参数的键
*ServletContext getServletContext()
5.Servlet 的细节
1> servlet线程安全问题 ==> 不是线程安全的.不要使用成员变量来接受线程相关的参数.要使用局部变量来接受线程参数.
2> servlet的启动==> <load-on-startup> 可以让servlet的实例随着服务器的启动而创建. 填入正整数. 一般来讲取值范围是0~5. 数值越小优先级越高.
3> servlet路径.
*相对路径匹配
<span style="white-space:pre"></span>/AServlet
<span style="white-space:pre"></span>/ABC/BCD/AServlet
<span style="white-space:pre"></span>/ ==> 可以与项目下任何路径匹配

匹配范围越大,优先级越低.
*后缀名匹配
<span style="white-space:pre"></span>*.do
*.action
*.xx
*.do 的 优先级 比 "/" 高.

6.ServletContext 对象
</pre><pre name="code" class="java"><span style="white-space:pre"></span>1.获得全局参数
<context-param>
<span style="white-space:pre"></span><param-name>name</param-name>
<param-value>tom</param-value>
</context-param>
*String getInitParameter(String name) 根据参数的键获得值
*Enumeration getInitParameterNames() 获得所有参数的键
<span style="white-space:pre"></span>2.域对象功能
Application ==> servletContext
session
request
page
域就是一个 用于通讯的map.
域的操作:
setAttribute(key,value)
getAttribute(key)
removeAttribute(key)
getAttributeNames()

3.获得项目内资源相关方法.

InputStream getResourceAsStream(String path) 填入相对路径("/"代表WebRoot下),返回文件的流.
String getRealPath(String path) 根据相对路径,返回文件的绝对路径.
//--------------------------------------------------------------------------------------------------------------------------------------
Response
Response对象,用于生成http相应信息. 对于开发人员来讲,就是 向response 对象中添加信息即可.
HTTP响应
<span style="white-space:pre"></span>*响应首行  HTTP协议/版本号 状态码(200 302 304 404 500)  状态码描述 
void setStatus(int sc) 设置状态码 200 302 304
void sendError(int sc) 设置状态码 404 500
void sendError(int sc, String msg) 同时设置状态和描述
*响应头 键:值
void addHeader(String name, String value) 添加一个响应头 无论如何都会新增一个头
|- void addCookie(Cookie cookie)
|- void addDateHeader(String name, long date)
|- void addIntHeader(String name, int value)
void setHeader(String name, String value) 设置一个响应头 不存在就添加,如果存在就修改(覆盖)
|- void setDateHeader(String name, long date)
|- void setIntHeader(String name, int value)
*响应空行 分隔符
*响应正文 请求的内容
getOutputStream() 字节流 输出文本,多媒体信息
getWriter() 字符流 输出文本.


例1: 手动向浏览器 发送404错误状态码.
例2: 访问BServlet,秒后浏览器自动跳转到传智首页.
例3: 手动做重定向效果.
例4: 向浏览器输出文字(字节流,中文)
例5: 向浏览器输出文字(字符流,中文)
例6: 向浏览器输出图片.(由servlet输出).
例7: 文件下载(向浏览器输出内容)
//--------------------------------------------------------------------------------------------------------------------------------------
Request
HTTP请求协议:
请求首行   请求方式 请求路径  协议名称/版本
request.getMethod(): GET 获得请求方式.
//--------------------------------------------------
request.getContextPath(): /day10-request 获得项目路径
request.getQueryString(): name=tom&age=18 获得访问地址中的键值对(只对get请求有效)
request.getRequestURI(): /day10-request/AServlet 获得请求路径(相对路径)
request.getRequestURL(): http://localhost:8080/day10-request/AServlet获得请求路径(绝对路径)
request.getServletPath(): /AServlet 获得servlet路径
//---------------------------------------------------
request.getRemoteAddr(): 0:0:0:0:0:0:0:1 打印出浏览器所在ip地址.
request.getRemoteHost(): 0:0:0:0:0:0:0:1 获得浏览器所在主机的名称(一般都是ip)
//---------------------------------------------------
request.getRemotePort(): 51153 获得浏览器访问的端口
request.getScheme(): http 获得协议名称
request.getServerName(): localhost 获得请求的主机名称
request.getServerPort(): 8080 获得请求的端口号
请求头键:值
根据键获得值一系列方法(开发中不常用)
String getHeader(String name) 根据请求头的键获得值
Enumeration getHeaderNames() 获得请求头中的所有键
int getIntHeader(String name)
long getDateHeader(String name)
Enumeration getHeaders(String name)
//------------------------------------------
request.getContentLength(): -1 获得请求正文长度
request.getContentType(): null
request.getLocale(): zh_CN
请求空行
请求正文 只有post提交才有正文.表单提交的键值对.
获得参数键值对.
一.如何获得表单提交上来的键值对.
api (要求背)
String getParameter(String key);
String[] getParameterValues(String key);
Enumeration getParameterNames();
Map<String,String[]> getParameterMap();
1> 提交方式为get时.
看图!
2> 提交方式为post时.
//因为post提交,是在获得参数的同时才进行解码. 那么我们就可以在获得参数之前设置解码码表.
//注意: 设置编码的代码一定要放到,获得参数代码之前
req.setCharacterEncoding("UTF-8");
//----------------------------------------------------------------------------------------------------------------------------------

Request的其他功能
1. 请求转发/请求包含
请求转发:
一个servlet里面处理逻辑, 将处理结果交给下一个Servlet(JSP)负责显示.
操作(代码):
<span style="white-space:pre"></span>request.getRequestDispatcher("/EServlet").forward(request,response);
问题:
1.在请求转发期间, 浏览器一共发送了几个请求?
1个请求
2.请求转发,会使浏览器的地址发生变化吗?
不会使地址栏发生变化
3.请求转发会改变请求方式吗? 如果AServlet中走的是doGet , 转发给BServlet, 会走BServlet那个方法?
不会改变请求方式. 第一个servlet 走doGet 那么下一个servlet一定也走doGet.
重定向 同如上3问. 
1.  2个请求.
2.  地址栏变化
3. 不一定. 因为第2个请求一定是get请求.  一个servlet重定向到另一个servlet. 第二个servlet一定走doGet.

注意:
servlet 向 jsp转发. servlet专注于逻辑处理。 JSP专注于显示处理结果。 不要在应该处理逻辑的地方做显示操作。也就是说在servlet中
不要使用字符流或字节流做任何输出的动作(不能添加响应正文)。 可以添加响应头。
//------------------------------------------------------------------------------------------------------------------------------------------
请求包含
一般请求包含不会在两个servlet中进行.都是在两个jsp中进行.
当在多个页面总有需要重复显示的内容. 我们可以把这段内容封装到一个jsp中. 以后凡是要显示这段重复的内容时,只需要把封装的jsp包含进来即可.
操作(代码):
<span style="white-space:pre"></span>request.getRequestDispatcher("/XXX").include(request,response);
2. Request域
request域就是一个放在request对象中的map.
request域范围:
与request对象的声明周期是一样的. 请求到达服务器时,request对象创建, 当服务器响应浏览器之后, request对象销毁. 
request域通常在请求转发时使用, servlet处理结果,将结果放置到request域中,带给jsp显示.
<span style="white-space:pre"></span>setAttribute(key,value)
getAttribute(key)
removeAttribute(key)
getAttributeNames()<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>
什么时候用转发?
servlet负责处理逻辑, jsp用于显示. 需要共享数据,一定要使用转发. 使用重定向会使数据丢失.
什么时候用重定向?
1. 当需要跳转到站内,并且地址栏要求发生变化时,使用重定向.前提是不需要共享数据.
2. 当需要跳转到站外时,一定只能使用重定向.