Servlet开发中注意的细节问题
- 客户端访问服务器的时候是通过URL访问的,所以我们要想用浏览器访问我们的Servlet的时候,我们就需要将我们的Servlet映射到一个URL上(通过我们的web.xml文件中的<servler-mapping>中的两个子标签<servlet-name>和<url-pattern>两个标签实现URL的配置,<Servlet>标签是注册了一个Servlet,只有注册了我们才能进行映射,而且注册一个可以映射多个,所以一个注册的Servlet会被多次映射,也就是可以被浏览器的多个url访问,而且我们的加一个后缀名也可以访问)
- /*、/news/*、/*.do 这三种方式的映射分别实现了不同的作用
/*:任何的路径都可以访问
/news/*:特定文件夹下的所有路径
/*.do:特定扩展名的所有路径
谁先被被匹配到???
谁的匹配度高就匹配谁,谁最像就匹配谁。*.do的优先级最低,两个原则。 - Servlet的单例问题:Servlet是一个供其他java程序调用的类,它不能独立运行,针对客户端的多次请求,通常状况下,Servlet只会创建一个Servlet实例对象,一旦创建它就会驻留在内存中,为后续的请求提供服务,直至退出web应用为止,也就是当我们关闭了浏览器之后我们的Servlet就终止了。
当Servlet第一次访问的时候,就被加载到内存中,以后该实例对各个请求服务,没次情况会调用一次service方法。
这样会出现什么问题:因为Servlet是单例的,所以会出现线程安全问题:
例如:售票系统(如果一个变量被多个用户共享,我们就需要实现同步机制,如果一个变量不需要共享直接在doGet或者doPost中定义,这样不会存在线程安全问题)
解决方法1:用这个对象将其synchronized(this){}包住,实现同步机制。
解决方法2: - servlet中配置<load-on-startup>配置的说明:
需求:当我们的网站启动的时候,可能会要求初始化一些数据(比如像创建一些临时的表),再比如我们的网站会有一些要定时完成的任务(定时写日志,定时发送邮件)
解决方法:可以使用配置这个标签然后结合一些线程相关的知识解决问题。
先说明<load-on-startup>:通过配置该标签,可以指定该Servlet自动创建。
实例1:初始化一些东西
实现:1、在Servlet标签中配置<load-on-startup>标签。2、在init函数中写要初始化的东西。
实例2:每隔1分钟发送一份电子邮件
实现:1、新建一个线程 2、调用线程,配置<load-on-startup>标签
public void init() throws ServletException { // Put your code here System.out.println("我们的线程启动了"); SendEmail send=new SendEmail(); send.sendmail(); }
package com.lyw.servlet; public class SendEmail extends Thread { public void sendmail(){ int i=0; while(true){ i++; try { Thread.sleep(10*1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("发送第"+i+"份邮件"); } } }
<load-on-startup>2</load-on-startup>
我们的<load-on-startup>标签中夹的数字是什么意思???有什么作用??
这代表我们启动是顺序,因为在实际开发中我们肯定要初始化多个对象,所以我们在这里要用数字表明启动的顺序。 - ServletConfig对象
该对象主要是用于读取Servlet的一些配置信息,
<init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param>
package com.lyw.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FirstServlet extends HttpServlet { 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); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here System.out.println("我们的线程启动了"); SendEmail send=new SendEmail(); send.sendmail(); } }
读取配置信息,该配置信息只能由该Servlet读取。但是,如果希望让所有的Servlet读取某个参数,应该这样配置:<contex-param>标签下配置的可以被任何Servlet读取。
- 如何去修改Servlet的文件
在myeclipse的plugin目录下输入wizards进行搜索找到相应的jar包,用压缩包打开之后进行修改,改成自己想要的样子,然后保存即可,修改的时候要把myeclipse关闭了。