15、Servlet

servlet 是运行在 Web 服务器中的小型 Java 程序 ( 服务器端的小应用程序 ) 。servlet 通常通过 HTTP(超文本传输协议) 接收和响应来自 Web 客户端的请求

 三大作用

1、获取表单数据

2、处理业务逻辑

3、分发转向

 

注意
修改了类名之后要在web.xml中修改一下servlet-name标签中的完整类名
<url-pattern >/ servlet/demo4 </ url-pattern>:第一个/代表当前应用根目录
每次修改完之后要重新运行服务器或者redeploy
在Windows下复制的目录为反斜杠\,正反都支持,但是\需要转义,故一般使用正斜杠/
 

一、编写一个servlet程序

(1)写一个java类,实现servlet接口

1 public class ServletTest implements Servlet{
2     // 接收用户请求并作出相应
3     public void service(ServletRequest req, ServletResponse res)
4             throws ServletException, IOException {
5         // TODO Auto-generated method stub
6         res.getWriter().write("hello");
7     }
8 }

(2)修改web.xml文件,给servlet提供一个可访问的URI地址

 1 <!-- 创建一个servlet实例 -->
 2 <servlet>
 3     <servlet-name>servletDemo</servlet-name>
 4     <servlet-class>cn.guojie.servlet.ServletTest</servlet-class>
 5 </servlet>
 6 
 7 <!-- 给servlet提供(映射)一个可访问的URI地址 -->
 8 <servlet-mapping>
 9     <servlet-name>servletDemo</servlet-name>
10     <url-pattern>/demo1</url-pattern>
11 </servlet-mapping>

servletDemo:servlet的名字,自定义,和mapping中要相同

url-pattern:/demo1代表测试的时候用的

(3)部署应用到tomcat服务器

(4)测试:http://locahost:8080/servlet/demo1 --> servlet-mapping标签中的/demo1,通过servlet名servletDemo  --> servlet标签中servletDemo的servlet名 -->cn.guojie.servlet.ServletTest相当于实例化cn.guojie.servlet.ServletTest类,类是服务器实例化的,service方法也是服务器调用的

 javax是javaEE的,以后不再是Swing的

 

二、执行过程

 

 

三、Servlet生命周期

实例化(构造)-->初始化(init)-->服务(service,多线程)->销毁(destory)
实例化-->初始化:第一次访问Servlet就出生(默认情况下)
服务:应用活着,servlet就活着(每次访问都被调用)
销毁:应用卸载了servlet就销毁
 
deploy部署
undeploy卸载
 
让servlet在服务器启动时就创建
1 <servlet>
2         <servlet-name>servletDemo</servlet-name>
3         <servlet-class>cn.guojie.servlet.ServletTest</servlet-class>
4         <load-on-startup>2</load-on-startup>  <!-- 数值越高,优先级越高,不要写0,让servlet在服务器启动时就创建 -->
5     </servlet>

 

四、Servlet的三种创建方式

1、实现javax.servlet.Servlet接口
2、继承javax.servet.GenericServlet类(适配器模式)插座,实现多个接口,重写了多个方法
3、继承javax.servlet.http.HttpServlet类(模板方法设计模式)(开发中常用方式)
 1 // 不要在重写父类的service方法
 2 @Override
 3 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 4         throws ServletException, IOException {
 5     System.out.println("doget");
 6 }
 7 
 8 @Override
 9 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
10         throws ServletException, IOException {
11     System.out.println("dopost");
12 }
继承的HttpServlet中service方法,调用service方法判断是get还是post请求,之后再根据请求用doGet还是doPost方法处理
右键创建servlet就是创建的HttpServlet的实现类。
 
模板设计思想(多态)
接口Servlet s = new ServletDemo();
s.service()是调用ServletDemo的service方法,ServletDemo没有,则找其父亲HttpServlet的service方法,HttpServlet重写了service方法,里面doGet或是doPost判断是get还是post请求,而ServletDemo中重写了doPost和doGet方法,执行ServletDemo中的这两个方法,要是在ServletDemo中重写了doPost和doGet方法,模板设计模式就无效了,无法区分doGet或是doPost
 
继承图
 HttpServlet (继承HttpServlet) --> GenericServlet --> Servlet (小到大)
 
使生成的servlet更清新一些
找到:MyEclipse\Common\plugins目录
把com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar复制到上面目录
 
改了web.xml之后要在服务器中重新部署应用
 
带三角的是继承过来的,不带的是自己的

 

 xml配置信息写错报错,检查配置文件是否写错

 

 

servlet映射细节

1、只要servlet-name相同,url-pattern不同也可以通过url-pattern中不同的地址访问同一servlet,多个映射路径
2、通配符* 代表任意字符串
url-pattern: *.do 以*.字符串的请求都可以访问 注:不要加/
url-pattern: /* 任意字符串都可以访问
url-pattern: /action/* 以/action开头的请求都可以访问
 
匹配规则:
优先级:从高到低
绝对匹配> /开头匹配 >扩展名方式匹配
如果url-pattern的值是/,表示执行默认映射。所有资源都是servlet
在tomcat的conf配置文件中的web.xml中配置为/
1 <servlet-mapping>
2     <servlet-name>default</servlet-name>
3     <url-pattern>/</url-pattern>
4 </servlet-mapping>

 

五、Servlet的线程安全

单实例:每次访问多线程
解决线程安全问题的最佳办法,不要写全局变量,而写局部变量(每次进去都是初始化为1,分页的时候有用)
SingleThreadModel会每次访问一次建一个;用线程会造成线程不安全
 

六、Servlet获取配置信息

ServletConfig的使用

作用一:可以获取servlet配置信息

方式1:重写父类GenericServlet的init方法初始化
1 // web.xml中的配置信息
2 <servlet>
3   <servlet-name>ServletConf</servlet-name>
4   <servlet-class>cn.guojie.servletConf.ServletConf</servlet-class>
5   <init-param>
6       <param-name>encoding</param-name>
7       <param-value>GBK</param-value>
8   </init-param>
9 </servlet>
 1 private ServletConfig config;
 2 
 3 // 重写父类GenericServlet的init方法初始化得到ServletConfig对象,此对象由服务器创建
 4 @Override
 5 public void init(ServletConfig config) throws ServletException {
 6     // TODO Auto-generated method stub
 7     this.config = config;
 8 }
 9 
10 public void doGet(HttpServletRequest request, HttpServletResponse response)
11         throws ServletException, IOException {
12     String parameter = config.getInitParameter("encoding");  // 获取配置文件信息
13     System.out.println(parameter);;
14 }

 

方式2:(常用)

1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     // 通过祖先Servlet的getServletConfig方法获得ServletConfig
4     this.getServletConfig().getInitParameter("encoding");
5 }

 

方式3:
1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     // HttpServlet已经实现了ServletConfig接口
4     String parameter = this.getInitParameter("encoding");
5     System.out.println(parameter);
6 }

 

作用二:可以获得ServletContext对象

 

 七、ServletContext (重要

 ServletContext: 代表的是整个应用,一个应用只有一个ServletContext对象,单实例,服务器启动的时候创建,服务器关闭或者应用卸载时销毁
 

作用:

1、域对象
在一定范围内(当前应用),使多个Servlet共享数据。
ServletContext 维护一个map存储键值对
常用方法:
1 void setAttribute(String name,object value);  // 向ServletContext对象的map中添加数据
2 Object getAttribute(String name);  // 从ServletContext对象的map中取数据
3 void rmoveAttribute(String name);  // 根据name去移除数据

 

1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     // 调用GenericServlet的方法得到
4     ServletContext application = this.getServletContext();
5     // 向ServletContext对象的map中添加数据
6     application.setAttribute("name", "guo");
7     // 通过反射获取对象所属类名
8     application.getClass().getName();
9 }
1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     // 从ServletContext对象的map中取数据
4      String name = (String) this.getServletContext().getAttribute("name");
5      System.out.println(name);
6 }

 

2、获取全局配置信息
修改web.xml文件:
getInitParameter ( String name) //根据配置文件中的key得到value
1 <context-param>
2     <param-name>encoding</param-name>
3     <param-value>UTF-8</param-value>
4 </context-param>
1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     // 获取全局配置信息
4     String encoding = this.getServletContext().getInitParameter("encoding");
5     System.out.println(encoding);
6 }

 

 3、获取资源路径
String getRealPath(String path);  //根据资源名称得到资源的绝对路径.
可以得到当前应用任何位置的任何资源(properties、xml...)
ResourceBundle只能取到src目录下的class(myeclipse和服务器中相对应)
不要忘了当前路径的/
1 // 获取在web-info文件夹下的文件
2 private void test1() throws IOException, FileNotFoundException {
3     String realPath = this.getServletContext().getRealPath("/WEB-INF/a.properties");  // /是当前应用根目录,部署在服务器上,故目录要是服务器上的目录,而不是myeclipse的
4     System.out.println(realPath);
5     Properties p = new Properties();
6     p.load(new FileInputStream(realPath));
7     String value = p.getProperty("name");
8     System.out.println(value);
9 }
1 // 获取src目录下的b.properties
2 private void test2() throws IOException, FileNotFoundException {
3     String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/b.properties");
4     System.out.println(realPath);
5     Properties p = new Properties();
6     p.load(new FileInputStream(realPath));
7     String value = p.getProperty("name");
8     System.out.println(value);
9 }
1 // 获取包下面的b.properties
2 private void test3() throws IOException, FileNotFoundException {
3     String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/cn/guojie/servletContext/c.properties");
4     System.out.println(realPath);
5     Properties p = new Properties();
6     p.load(new FileInputStream(realPath));
7     String value = p.getProperty("name");
8     System.out.println(value);
9 }

 

4、实现Servlet的转发
RequestDispatcher getRequestDispatcher ( String path) ;//参数表示要跳转到哪去

1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2         throws ServletException, IOException {
3     
4     ServletContext application = this.getServletContext();
5     // 像下传递,将应用转发到/servlet/Demo6应用,在web.xml中可看到
6     application.getRequestDispatcher("/servlet/demo5").forward(request, response);
7 }
 

八、Servlet相关对象

Servlet                         接口javax.servlet.Servlet  
GenericServlet              抽象类javax.servlet.GenericServlet    
HttpServlet                  抽象类javax.servlet.http.HttpServlet   
ServletConfig               接口javax.servlet.ServletConfig 
ServletContext             接口javax.servlet.ServletContext     
ServletRequest             接口javax.servlet.ServletRequest   
ServletResponse           接口javax.servlet.ServletResponse     
HttpServletRequest      接口javax.servlet.http.HttpServletRequest  
HttpServletResponse    接口javax.servlet.http.HttpServletResponse  
 
RequestDispatcher       接口javax.servlet.RequestDispatcher  
 
UML
如果是通过参数传过来的对象,就叫依赖
通过方法得到的对象,就叫关联

 

 
 
 

 

posted @ 2016-12-05 00:06  十年英雄梦  阅读(139)  评论(0编辑  收藏  举报