Servlet 简要概述

来源:互联网 发布:萨克斯怎么挑选知乎 编辑:程序博客网 时间:2024/06/03 18:12

Servlet是什么

就是运行在服务器端的 Java小程序

 

Servlet执行步骤:

1) 客户端发送请求至服务器端;

2) 服务器将请求信息发送至 Servlet

3) Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;

4) 服务器将响应返回给客户端。

 

Servlet的生命周期

A.加载和实例化:在第一次请求Servlet的时候,Servlet容器会创建Servlet实例;

B.初始化:容器加载完Servlet后,必须先进行初始化,调用init方法;

CServlet初始化后,处于响应请求的就绪状态,如果有客户端请求发送,则调用Servlet实例的service()方法,并根据请求方式,调用 doPost 或者 doGet方法

D.最后,Servlet容器负责销毁Servlet实例,调用destroy方法。

注意:

对于多次请求,Server创建会创建新的请求和响应对象,但是只调用一次init方法;

一般关闭Server时,调用destroy方法。

 

Servlet的配置文件(初始化参数配置)

在web.xml中配置:

<servlet>    <servlet-name>InitConfigParam</servlet-name>    <servlet-class>com.practice.InitConfigParam</servlet-class>  <init-param>  <param-name>userName</param-name>  <param-value>xiao</param-value></init-param><init-param><param-name>password</param-name><param-value>22</param-value></init-param></servlet><servlet-mapping>    <servlet-name>InitConfigParam</servlet-name>    <url-pattern>/InitConfigParam</url-pattern></servlet-mapping>

 

注意:上下两个 <servlet-name> 的值必须保持一致,完全一样

            <init-param>用来配置初始化参数,需要的时候才配置

 

 

ServletContext:

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。

     1> servletContext的作用:

              a>获取全局的初始化参数

              b>实现资源的共享

              c>获取web资源

     2>如何获取servletContext

          a>this.getServletConfig.getContext()

          b>this.getContext()

     3>如何实现资源的共享的呢?

ServletContext context = this.getServletContext();  

//存入共享的数据   

context.setAttribute("name", "haha");

在其它的Servlet中利用ServletContext对象获取共享的数据  

/*获取ServletContext对象*/ 

ServletContext context = this.getServletContext();  

//获取共享的数据  

String name = context.getAttribute("name");  

System.out.println("共享的内容值是:"+name);

 

核心的类与接口  

A. Servlet接口  

B. GenericServlet抽象类  

C. HttpServlet抽象类  

D. ServletRequest,ServletResponse接口  

E. ServletConfig接口   

    ServletContext getServletContext();   

    String getInitParameter(StringparaName);  

F. HttpServletRequest接口   

    String getParameter(String name);   

    String[] getParameterValues(String name);   

    setCharacterEncoding(String code);   

    RequestDispatcher getRequestDispatcher(String url);   

    setAttribute(String name,Object obj);   

    Object getAttribute(String name);   

    removeAttribute(String name);   

    String getContextPath();   

    String getRequestURI();   

    HttpSession getSession()/getSession(boolean flag);   

    Cookie[] getCookies();

G. HttpServletResponse接口   

    setContentType(String str);   

    PrintWriter getWriter();   

    sendRedirect(String url);   

    encodeURL(String url);   

    encodeRedirectURL(String url);   

    addCookie(Cookie cookie);  

H. ServletContext接口   

    String getRealPath(String str);   

    setAttribute(String name,Object obj);   

    Object getAttribute(String name);   

    removeAttribute(String name);   

    String getInitParameter(String name);

 

 

表单处理

A.    读取表单中的参数

//方式一request.getParameter("username");//方式二:如果一个名字对应多个参数值,例如checkboxrequest.getParameterValues("checkbox");//返回一个String类型的数组//然后for循环输出//也可用  Map map =request.getParameterMap();  String[] items =(String[])map.get("checkbox");//当然 如果checkbox没有任何的值选定 要做个判断if(s==null)..........//方式三:如果servlet中不知道有哪几个参数名称Enumeration e =request.getParameterNames()String parameterName = null;while(e.hasMoreElements()) {parameterNames = (String) e.nextElement();String values[] = request.getParameterValues(parameterName);out.pritnln(parameterName); //然后用for循环输出}//方式四:与3方法类似 道理一样 ;方法不同Map map  =request.getParameterMap()Set set  =map.keySet();   //set为所有参数名称Iterator it  = set.iterator();String parameterNames = null;while(it.hasNext()) {parameterName=(String)it.next();String values[] = request.getParameterValues(parameterName);out.println(parameterName);//然后用for循环输出}

 

B.     处理中文乱码

 1.用 post 方法提交表单

 2.在接收参数的页面写上 response.setContentType("text/html;charset=utf-8");

 3.接收到参数后进行编码转换  new String(request.getParameter("***").getBytes("iso-8859-1"), "utf-8");

 

Get请求与 post请求

默认是 get请求,表单中指定用 post则用 post请求

区别:

post 请求比 get 请求更安全,因为 get 请求会把提交的信息显示在地址栏 URL上,post 不会

get 请求传递的数据大小受到URL 长度的限制,多了会丢失数据,而 post 请求则几乎不受长度限制

get 请求的默认编码是 ASCII ,post 请求的默认编码是 ISO

post 发送数据并不提前转换编码,发送过来之后可以设置编码格式,而get发送数据是发送过来之前就已经编码了,并不能在接收数据的时候设置编码
 post方式提交的数据可以设置请求编码格式
  request.setCharacterEncoding("utf-8");

 get方式提交的的数据需要做编码转换
  //获取表单数据
  String  userName   = request.getParameter("userName");
  //转换字符编码格式
  name = new String(userName.getBytes("iso-8859-1"),"utf-8");

 

 

转发(forward)与重定向(sendRedirect)

转发:客户端访问资源A,资源A让资源B给客户端构造了响应返回数据,使用RequestDispatcher对象的forward()

           request.getRequestDispatcher("main.jsp").forward(request, response);

重定向:客户端访问资源A,资源A给浏览器构造了响应,告诉浏览器去请求资源B,资源B给浏览器构造了响应使用           

              response.sendRedirect("welcome.jsp");

区别:

跳转方式                                                  请求转发                                                                        重定向

目标范围                                    只能转发到一个WEB应用的组件                        可以是同一个WEB应用,也可以是其他站点

"/" 开头含义                              表示WEB应用程序的根目录                                表示整个WEB站点的根目录

地址栏显示URL                        请求转发结束后,地址栏URL保持不变             重定向结束后,地址栏URL变成目标URL

请求对象和响应对象               只产生一次请求对象和响应对象                          会产生两次请求对象和响应对象

                                                     资源A和资源B共享相同的请求和响应对象

 

 

Cookie

首先来了解什么是“会话”。会话是web技术中的一个术语,可以简单的理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,这个过程称为一个会话。

如果在打开一个浏览器访问一个页面后,再打开一个浏览器访问同一个页面,那这就是有两个会话;而打开一个浏览器访问一个页面后,通过这个页面上的某个超链接是从新的浏览器打开的,那依然只算一个会话。

Cookie技术是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器时,就会带着各自的数据过去,这样web服务器处理的就是用户各自的数据了。

如何创建获得删除 cookie:以下是关键代码

   String name = request.getParameter("username");
   String passwd = request.getParameter("passwd");
   Cookie cookie = new Cookie(name, passwd);//创建 cookie
   response.addCookie(cookie);//添加到客户端

   Cookie[] cookies = request.getCookies(); //获取 cookie
   out.print("Cookie 中属性名和属性值的对应关系如下:<br/>");
 
 if(cookies != null) {//循环输出
  for(int i = 0; i < cookies.length; i++) {
   Cookie ck = cookies[i];
   String cookieName = ck.getName();
   String cookieValue = ck.getValue();
   out.println("name == " + cookieName + ",value == " + cookieValue);
    }
 }
 
 cookie.setMaxAge(0);//删除 cookie

 

Session

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,

由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中

的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
当用户打开浏览器,访问某个网站操作session时,服务器就会在服务器的内存为该浏览器分配一个session对象,该session对象被这个浏览器独占。
这个session对象也可以看做是一个容器,session默认存在时间为30min,可以修改。

 

得到session

// 返回这个request绑定的session对象,如果没有,则创建一个
HttpSession session = request.getSession();
// 返回这个request绑定的session对象,如果没有,则根据create的值决定是否创建一个
HttpSession session = request.getSession(boolean create)

//向session中添加属性

session.setAttribute(String name,Object val);

//从session中得到某个属性

String value = session.getAttribute(String name);

//从session中移除某个属性

session.removeAttribute(String name);

 

 

常用方法:

String getId();

String getRealPath(String str);

setAttribute(String name,Object obj);

Object getAttribute(String name);

setMaxInactiveInterval(int seconds);

invalidate();

ServletContext getServletContext();

 

禁止cookie后,如何继续使用 session

使用 Url 重写:

如何实现 url重写

encodeURL(String url);

encodeRedirectURL(String url);

1.jsp
<%
session.setAttribute("hi","Do you work or are you a student?");
%>

<a href="<%=response.encodeURL("2.jsp")%>">2.jsp</a>

2.jsp
<%=session.getAttribute("hi")%>

注意:

由于Cookie的禁用,这次请求协议头中虽然没有携带SessionID的信息,但SessionID的信息作为请求地址的一部分传到了服务器端,这就是URL重写的意义所在。

response的encodeURL方法将根据浏览器是否不支持Cookie决定是否将SessionID信息写入链接地址。

 

 

DAO

DAO是Data Access Object数据访问接口,数据访问:故名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
DAO的功能:
1. DAO用来封装Data Source的..就比如,Connection conn = DAOFacotry.createConnection();
就可以把Driver. URL. username, passpword这一些放在DAO中
以后要更改数据库的类型.比如要把MySQL换成Oracle的话,只需要更改DAOFacory里面的getConnection()里面的Driver.URL.之类的。
2. DAO也是把对数据库的操作(比如最基本的CRUD操作)全部封装在里面..
比如说要要插入一个新的用户,那么在DAO中只需要提供一个insertUser(User user)这一个方法就可以了,具体的操作是在DAO中实现的。
那么对于要调用DAO的时候.只要知道insertUser(User)是用来插入一个新的用户,而不需要知道是如何实现的。

 

过滤器

web.xml中元素执行的顺序listener->filter->struts拦截器->servlet

过滤器的概念

Java中的Filter并不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。

优点:过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题

过滤器的作用描述

· HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest 

· 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。 

· HttpServletResponse到达客户端之前,拦截HttpServletResponse 

· 根据需要检查HttpServletResponse,可以修改HttpServletResponse头和数据。

web.xml中的配置

<!-- 编码过滤器 -->      <filter>         <filter-name>setCharacterEncoding</filter-name>     <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class>         <init-param>             <param-name>encoding</param-name>             <param-value>utf-8</param-value>         </init-param>      </filter>      <filter-mapping>         <filter-name>setCharacterEncoding</filter-name>         <url-pattern>/*</url-pattern>      </filter-mapping>  <!-- 请求url日志记录过滤器-->      <filter>  <filter-name>logfilter</filter-name>  <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class>      </filter>      <filter-mapping>  <filter-name>logfilter</filter-name>  <url-pattern>/*</url-pattern>      </filter-mapping><!-- 自定义过滤器--> <filter>      <filter-name>IPFilter</filter-name><filter-class>com.practice.IPFilter</filter-class><init-param><param-name>ip</param-name><param-value>127.0.0.1</param-value></init-param>    </filter>    <filter-mapping>      <filter-name>IPFilter</filter-name>      <url-pattern>/*</url-pattern>    </filter-mapping>


 

监听器

Servlet监听器是Servlet规范中定义的一种特殊类,用于监听ServletContextHttpSessionServletRequest等域对象的创建与销毁事件,以及监听这些域对象中属性发生修改的事件。

 

监听对象:

1ServletContextapplication,整个应用只存在一个

2HttpSessionsession,针对每一个对话

3ServletRequestrequest,针对每一个客户请求

监听内容:创建、销毁、属性改变事件

监听作用:可以在事件发生前、发生后进行一些处理,一般可以用来统计在线人数和在线用户、统计网站访问量、系统启动时初始化信息等。

 

监听器的基本使用

创建步骤:

1、创建一个实现监听器接口的类

2、配置web.xml文件,注册监听器

<listener>

    <listener-class>完整类名</listener-class>

</listener>

监听器的启动顺序:按照web.xml的配置顺序来启动

加载顺序:监听器>过滤器>Servlet

 

 

servlet的线程安全问题

1servlet线程安全问题产生的原因在默认情况下,容器只会为每一个servlet类创建唯一的一个实例,当有多个请求到达容器,就有可能有多个线程同时访问同一个实例。

2、解决方式

1)使用局部变量:多线程不共享局部变量

2)使用同步代码块:要尽量缩小同步块的范围,否则影响效率

3)servlet的属性尽量设置成可读的,不要去修改。

4)不要再Servlet中创建自己的线程要完成某个功能,会导致线程执行复杂化,出现线程安全问题

原创粉丝点击