Servlet基础
创建一个Servlet
- 实现servlet接口即可.
- 继承javax.servlet.GenericServlet
- 继承javax.servlet.http.HttpServlet
- 重写init、service方法
- 在Web.xml中注册
- 发送请求,在浏览器中输入
http://localhost:8080/项目名/AServlet
<servlet>
<servlet-name>AServlet</servlet-name>
<servlet-class>完整类路径</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AServlet</servlet-name>
<url-pattern>/AServlet</url-pattern>
</servlet-mapping>
Servlet生命周期
- 在构造函数后之后调用init方法
- service方法 ,当请求发来时,处理请求使用.
- destory方法, 当服务器关闭时,会销毁servlet,在销毁之前调用该方法释放资源.
Servlet访问时序
- 浏览器发送请求
- 服务器分析请求,请求哪个主机,哪个项目
- 查找Web.xml下是否存在Servlet资源
- 如果第一次访问,创建Servlet实例
- 调用Servlet中的init方法,将Servlet的实例存储在内存中
- 调用service方法,传递request和response参数
- 将request和response传给服务器
- 服务器将response组装成HTTP响应协议
- 将HTTP响应协议还给客户端
Servlet其他方法
getServletInfo ==> 获得servlet的信息(版本,作者,版权..),没用.
getServletConfig ==> 返回servletConfig对象.
ServletConfig对象
- getServletName:获得配置文件中servlet-name 元素的内容
- getInitParameter(param-name):格局param-name获取param-value
- getInitParameterNames:返回所有param-name,类型为Enumeration
- getServletContext();
在Web.xml中的servlet标签中添加
<init-param>
<param-name>name</param-name>
<param-value>tom</param-value>
</init-param>
在servlet中创建ServletConfig对象,在init方法中通过参数赋值。
在getServletConfig方法中返回ServletConfig对象
在servlet类中
Enumeration<String> en=getServletConfig().getinitParameterNames();
String value=getServletConfig().getInitParameter(en.nextElement());
GenericServlet设计
- 实现servlet接口和servletconfig接口
- 将service方法设为abstract
- 通过getServletConfig的方法实现servletconfig接口中的方法
- 创建Servletconfig对象,在init中初始化为参数值
创建init()无参方法,在init中调用此方法 - 实现getservletconfig方法,将getServletInfo的范围值设为空白字符串
- 继承这个类即可。
HTTPServlet设计
由于项目都是基于HTTP协议,而service参数为ServletRequest,因此可转为HTTp的
1. 继承GenericServlet。
2. 在service方法中创建HttpServletRequest和HttpServletResponse对象,将方法参数强制类型转为这两个对象,调用service方法,参数为这两个对象
3. 创建service方法,参数和上面两个对象类型相同
调用request的getMethod方法,返回字符串
如果字符串等于“POST”,调用doPost(request,response)方法,
等于“GET”,调用doGet(request,response)方法
4. 创建这两个方法,将类设为抽象类
5. 继承这个类,根据method的不同重写不同的方法doGet或doPost
public static final String Method_get="GET";
public static final String Method_post="POST";
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest request=null;
HttpServletResponse response=null;
try {
request=(HttpServletRequest)req;
response=(HttpServletResponse)res;
service(request, response);
} catch (Exception e) {
// TODO: handle exception
}
}
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//根据请求不同做不同的事情
//获得客户端请求方式
String method=req.getMethod();
//根据请求方式,调用不同方法
if(method.equals(Method_get)){
doGet(req,res);
}else if(method.equals(Method_post)){
doPost(req,res);
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res) {}
public void doGet(HttpServletRequest req, HttpServletResponse res) {}
Servlet线程安全
因为在servlet运行期间只有一个servlet实例存在.可能会同时处理多个请求.那么我们在servlet中声明成员变量来存储用户数据是有线程安全问题的.
实现SingleThreadMode接口
在请求发出时,创建一个Servlet实例,当使用完时,放入栈中。以后再用时,从栈中取出。
这样当多个请求发出时,先查看栈中是否有实例,如果有,直接取出,如果没有,则创建实例。
可能造成成员变量的值发生变化,不推荐使用
使用局部变量
Servlet随着服务器启动
使用Web.xml的load-on-startup配置实现,值为数字,优先级一样则按配置顺序
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
<!--值越小,越先启动-->
<load-on-startup>3</load-on-startup>
</servlet>
servlet的路径配置url-pattern
- 路径匹配
/AServlet - 后缀名匹配
只要在路径中使用和后缀名匹配的字符串即可打开响应页面
例如*.do 只要在路径中输入任意字符,最后为.do,就打开这个servlet
配置的路径匹配范围越大,优先级越低
Web.xml
- 在conf文件夹下有一个web.xml文件
- 当输入的路径不存在时,调用这个文件的名为default的servlet,抛出404异常
- 处理jsp文件时,在conf下的web.xml下匹配,存在jsp的url-pattern,调用jsp的servlet引擎进行处理。
- 在web.xml中又所有的mime类型。格式
<mime-mapping>
<extension>xml</extension>
<mime-type>application/xml</mime-type>
</mime-mapping>
ServletContext对象
通过servletConfig的getServletContext获得
封装了web.xml中的配置
获得项目中资源
1. getinitParameter和getInitParameterNames是web.xml的全局param
而ServletConfig的方法是获取servlet标签下的param
<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>
- 对应application域,一个项目中只有一个context实例
setAttribute(key,value)
getAttribute(key)
removeAtribute(key)
getAttributeNames() - 获取项目中的资源
在WEB-INF文件夹下新建xml文件,例如stu.xml
在Tomcat下
ServletContext sc=getServletContext()
InputStream is=sc.getResourceAsStream(“/WEB-INF/stu.xml”);
sc.getRealPath(“/WEB-INF/stu.xml”)//获取资源绝对路径
//获取项目下面的资源文件
加“/”代表classes目录
this.getClass().getResourceAsStream(“/stu.xml”);
不加“/”代表类文件所在目录
this.getClass().getResourceAsStream(“stu.xml”);
//使用类加载器获得,加不加“/”都为classes目录
this.getclass().getClassLoader().getResourceAsStream(“”)
response
组成:响应首行(协议/版本号,状态码,状态码描述)、响应头、响应空行、响应正文
1. setstatus(int,string)设置状态码和描述
2. sendError(int string)设置错误状态码(404,500)
3. addHeader(name,value)
4. setHeader(name,value)
5. add/setInt/DateHeader()设置响应头
重定向
- 使用response的setStatus方法,参数为302
- 使用setHeader(),键为任意字符串,值为地址,则重定向到指定网址
- 或者使用response的sendRedirect(string)直接定向,不需要设置状态码
5秒后跳转refresh
使用response的setHeader(“Refresh”,”5;url=http://www.baidu.com“);
字节流发送中文
servlet默认iso-8859-1编码方式
浏览器默认GBK编码
OutputStream os=response.getOutputStream();
os.write("String".getBytes());//无乱码,在方法的参数中输入utf-8出现乱码
可通过输出<meta content=“text/html;charset=utf-8”>
还可通过response.setHeaders("Content-Type","text/html;charset=utf-8")
字符流发送中文
response.setCharacterEncoding("utf-8");//控制输出流的编码方式
PrintWriter pw=responser.getWriter();
pw.print("你好,世界");//不设置编码方式出现乱码
使用response.setContentType("text/html;charset=utf-8");
字节流发送图片
- 获取mime类型
getServletContext().getMimeType(.后缀名);返回mime字符串 - 设置mime类型
response.setContentType(“image/jpeg”); - 获取图片输入流
InputStream is=getServletContext().getResourceAsStream(“/WEB-INF/one.jpg”); - 通过response获得字节流
OutputStream out=resp.getOutputStream(); - 两个流对接
byte[] buffer=new byte[1024];
int len=0;
while ((len=is.read(buffer))>0) {
out.write(buffer,0,len);
out.flush();
}
is.close();
字节流发送文件
将response的setContentType改为使用setHeader(“Content-Disposition”,attachment;filename=ValidateCode.jar);
request
封装了浏览器发送的信息
包括请求首行,请求头,请求空行,请求正文
常用方法
- getContentLength()请求正文长度
- getContentType()请求正文内容
- getContextPath()获取项目路径/项目名
- getMethod()获取请求方式get或post
- getLocale()获取语言区域
- getRequestURI()请求地址的相对路径/项目名/AServlet
- getRequestURL()绝对路径http:
- getServletPath()获取请求地址/Aservlet
获取参数
- getParameter(“key”)
- getParameterMap()返回的map类型为string,string[]
- getParameterNames()
- getParameters(“key”)返回数组
request中文乱码
Get方式
- 在conf文件夹下的servlet.xml文件中的Connector标签下的URIEncoding改为utf-8
- 还可以在代码中获取到字符串后,通过getbytes(“ISO-8859-1”),获取byte数组
创建string对象,构造器参数为byte数组和utf-8编码
Post方式
post参数解码的时机是在调用getparameter之前,因此只需设置解码
request.setCharacterEncoding(“utf-8”);
request请求转发
一般将servlet处理后的数据发送给jsp
request.getRequestDispatcher(“/one.jsp”).forward(requset,response);jsp在WebContent目录下
在servlet中不要输出正文,但可以设置响应头
request请求包含
request.getRequestDispatcher(“/one.jsp”).include(requset,response);
request域
request.setAttribute(“key”,“value”)
request.getAttribute(“key”);
用到的路径
客户端路径
form的action属性
a的href属性
img的src属性
response的sendRedirect方法
请求头的refresh:3;url=“”
路径写法
- 带“/”,“/”相对于主机,在“/”后接项目名称
- 不带“/”,开发中不要出现,代表从当前目录找
服务器路径
url-pattern
request的getRequsetDispatcher方法
带“/”,相对于项目