面试题:请简述servlet的生命周期(工作流程)
servlet被web服务器调用
解:当servlet第一次被调用的时候,会触发init函数,该函数会把servlet实例装载到内存,init函数只被调用一次
然后会调用servlet的service方法(函数),
当第二次访问该servlet的时候就直接调用service函数
当web应用reload或者关闭tomcat,都回去调用distory函数,该函数就回去销毁servlet
知识点:form表单提交数据 get和post的区别
1.从安全性看,get<post,get提交的数据会在浏览器的地址栏显示
2.从提交内容的大小看,get提交的数据不能大于2K,而post提价的数据理论上不受限制
但实际编程中建议不要大于64K
3.从请求相应速度上看,get>post,get要求服务器立即处理请求,而post请求可能形成一个队列请求
servlet细节
Servlet单例问题
当servlet被第一次访问后,就被加载到内存,以后该实例对各个请求服务,即在使用中是单例
因为servlet是单例,所以会出现线程安全问题 比如:
售票系统 如果不加同步机制 ,则会出现为题
这里有一个原则:
(1)如果一个变量需要多个用户共享,则应在访问该变量的会后加上同步机制
写法: synchronized (对象/也可以直接写this) {//同步机制
//同步代码
}
(2)如果一个变量不需要共享,则直接在doget(),或者dopost()中定义
(3)servlet中的<load-on-satrtup>配置,(配置了<load-on-satrtup>后就可以不需要进行
<servlet-mapping>映射)
需求:当我们的网站启动的时候,可能会要求初始化一些数据(比如创建临时表)
再比如我们的网站有一些要求定时完成的任务(定时写日志,定时备份数据,定时发送邮件)
解决方法:可以通过<load-on-satrtup> 配合线程知识完成
先说明<load-on-satrtup>:通过配置<load-on-satrtup>可以使某个servlet自动创建
例:模拟定时发送电子邮件
1.遍写一个线程:EmailThread
package servlet1;
public class EmailThread extends Thread{
//继承Thread类,重写它的run方法
public void run() {
int i =0;
try {
while (true) {
Thread.sleep(10*10000);//每间隔10秒钟,发送一个邮件
System.out.println("这是发送的第"+(++i)+"份邮件");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.编写一个servlet类 :EmailServlet
package servlet1;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EmaiServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public EmaiServlet() {
super();
}
public void init(ServletConfig config) throws ServletException {
//创建一个线程
EmailThread email = new EmailThread();
email.start();//打开线程
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
public
void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.在web.XML中的配置
<servlet>
<!-- servlet的类名 -->
<servlet-name>MyServlet</servlet-name>
<!-- servlet类的全路径 -->
<servlet-class>com.sxt.EamilServlet</servlet-class>
<!--这里的数字1是代表这个servlet是第几个运行,启动的顺序-->
<load-on-satrtup>1</load-on-satrtup>
</servlet>
ServletConfig对象
(1) 该对象主要用于读取servlet配置信息
案例:
<servlet>
<servlet-name>MyServlet3</servlet-name>
<servlet-class>servlet1.MyServlet3</servlet-class>
<!-- 这里可以给servlet配置信息,这里配置的信息只能被该servlet读取 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<!-- 如果这里配置的参数,可被所有的servlet读取 -->
<context-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</context-param>
如何使用:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
String encoding = this.getServletConfig().getInitParameter("encoding");
response.setCharacterEncoding(encoding);
PrintWriter out = response.getWriter();
out.print("编码是"+encoding);
如果要把所有的参数都读取的话
比如
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>gbk</param-name>
<param-value>1.0</param-value>
</init-param>
<init-param>
<param-name>http</param-name>
<param-value>ddddd</param-value>
</init-param>
使用枚举进行遍历
//枚举,取出在web.xml当中所有配置的encoding
Enumeration<String> names =this.getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {//使用while循环进行遍历
String name = names.nextElement();
System.out.println(name);
System.out.println(this.getServletConfig().getInitParameter(name));
servletConfig对象:
1.获得字符集编码
2.获得数据库连接信息
3.获得配置文件,查看Struts案例的web.xml文件