JSP Servlet基础知识(二)



1.    HTML 是静态的,JSP是动态的,交互式的,而且可由用户定制。

 

2.    服务器:可能是物理主机(硬件),也可能是Web服务器应用(软件)。

客户:指人类用户,或浏览器应用。

Web客户允许用户请求服务器上的某个资源,并且向用户显示请求结果。

 

3.    服务器和客户的通信

服务器和客户之间对话的共同的语言是HTTP。

服务器使用HTTP向客户发送信息。

4.    HTTP

请求:HTTP方法(Get、Post),要访问的页面,表单参数。

响应:状态码,内容类型(文本、图片、HTML等),内容(具体的HTML、图片等)。

 

5.    HTTP请求:Get请求和Post请求

Get请求:资源的路径URL以及所有参数都会包括在”请求行”中。

    请求行:  GET /select/selectBeer.jsp?color=dark&taste=malty HTTP/1.1

    请求首部:Host: www.wickedlysmart.com

             User-Agent: Mozilla/5.0……

             Accept: text/html,application/xml,application./xhtml+xml,

text/html;q=0.9

             Accept-Language: en-us, en;q=0.5

             Accept-Encoding: gizp,deflate

              Accept-Charset: ISO-8859-1,utf;q=0.7,*;q=0.7

             Keep-Alive:300

             Connection: keep-alive

    GET请求,没有体,参数只能放在请求行中,并且会显示在浏览器的输入地址中,不够安全。

POST请求:又称为“消息体”或“有效负载”,放在消息体中,长度不受限制。

    请求行:POST /advisor/selectBeer.do HTTP/1.1

    请求首部:同上

    消息体:(空行)color=dark&taste=malty

    简单的超链接默认是GET方法,如:<a href=”http://www.baidu.com”>link</a>

    Form表单默认也是GET方法。

    GET、HEAD、PUT是幂等的(注:GET和doGet()不同,GET方法是HTTP的,doGet()是Servlet的);POST不是幂等的。

 

6.    HTTP响应

包括响应首部和体

首部告诉浏览器使用的协议,请求是否成功,以及体中放入内容是什么类型

    HTTP/1.1 200 OK

    Set-Cookie: jsessionID=adfiifeeni23499v99wernnwerr; Pat=/testEL

    Content-Type: text/html(内容类型响应首部的值称为MIME类型,MIME类型告诉浏览器要接受的数据是什么类型,其值与HTTP请求首部中的Accept所列的值相关)

    Content-Length:397

    Date: Wed, 19 Nov 2003 03:25:40 GMT

    Server: Apache-Coyote/1.1

    Connection: close

体中包含了让浏览器显示的具体内容:

    (空行)

     <html>……</html>

 

7.    URL(Uniform Resource Locators)

http://www.smart.com:80/beeradvice/select/beer1.html

协议        服务器     端口          路径          资源

FTP的端口是 31,Telnet:23,SMTP:25,Time:37,POP3:110,HTTPS:443

 

8.    Web服务器不做的两件事情

a)      动态内容。Web服务器应用只提供静态页面,动态内容由Web服务器辅助应用(CGI)来完成。

b)      在服务器上保存数据。Web服务器把这些功能转给辅助应用进行处理。

 

9.    Web容器

 

Web服务器(Apache)得到一个指向servlet的请求,服务器不是把这个请求直接交给servlet本身,而是交给Web容器(Tomcat),由Web容器调用servlet。

Web容器管理和运行servlet,容器知道自己与Web服务器之间的协议,Web容器控制者servlet的生命周期,容器会自动地为它接收每个servlet请求并创建一个新的线程,Web容器负责把JSP代发翻译成真正的Java代码。

利用配置文件(web.xml)将servlet部署到容器

一个完全兼容的J2EE应用服务器必须有一个Web容器和一个EJB容器

 

Tomcat是一个Web容器,而不是一个完整的j2ee应用服务器,因为Tomcat没有EJB容器。

 

 

 

10.    JSP-Servlet执行流程

    1) 浏览器把请求数据发送给容器

    2) 容器根据URL找到正确的Servlet,并把请求传递给这个Servlet

    3) Servlet调用辅助应用寻求帮助

    4) 这个辅助应用返回一个回答,Servlet把这个回答增加到请求对象

    5) Servlet把请求转发给JSP

    6) JSP 从请求对象得到回答

    7) JSP为容器生成一个页面

    8) 容器把这个页面返回给客户

 

 

 

 

11.    Servlet的生命周期

 

12.    Servlet的属性和参数

a)      属性

有三种类型的属性,应用上下文(ServletContext)、请求(HttpRequest)和会话(HttpSession)

设置方法: setAttribute(String name,Object value)

获取方法:getAttribute(String name), 返回类型是Object

上下文(ServletContext)属性不是线程安全的,因为每个Servlet都可以访问。让上下文属性线程安全的做法:

同步服务器方法(即对doGet()doPost()方法添加synchronized)

同步服务器方法意味着servlet中一次只能运行一个线程,但是并不能阻止其它servletJSP访问这个属性。

同步上下文( synchronized(getServletContext()))

synchronized(getServletContext()){

               getServletContext().setAttribute("foo", "22");

               getServletContext().setAttribute("bar", "42");

}

会话属性:通常,一个客户同时只有一个请求,就算多个servlet能在单独的线程中访问会话属性,每个线程都是单独的请求,所以,这时会话属性是线程安全的。但是一个用户同时有多个请求时(用户同时打开多个浏览器去访问),会话属性是非线程安全的,通过同步HttpSession来达到线程安全。代码如下:

           HttpSession session=request.getSession();

           synchronized(session){

               session.setAttribute("foo", "22");

               session.setAttribute("bar", "42");

    }

b)      参数

应用上下文初始化参数、请求参数、servlet初始化参数

设置方法:servlet初始化参数只能在DD中设置

获取方法:getInitParameter(String name)

 

13.    Servlet接受提交的参数

a)      接受单个参数

String username=request.getParameter(“username”);

b)      接受多个参数

String [] parameters=request.getParameterValues(“sizes”);//sizes可以看做是表单中的复选框,如:

            <form action=”**.do”>

<intput type=checkbox name=sizes value=”1”>1

<intput type=checkbox name=sizes value=”2”>2

<intput type=checkbox name=sizes value=”3”>3

<input type=”submit”>

</from>

 

14.    ServletConfigServletContext

a)      ServletConfig对象

每个servlet都有一个ServletConfig对象,用于向servlet传递部署信息。

servlet初始化之前不能使用servlet初始化参数。

ServletConfig构建过程如下:

1)      容器读取当前servletDD(web.xml),包括servlet初始化参数(<init-param>)

2)      容器为这个servlet创建(new)一个新的ServletConfig实例

3)      容器为这个servlet初始化参数创建一个String /值对

4)      容器向ServletConfig提供名/值初始化参数的引用

5)      容器创建(new)serlvet类的实例

6)      容器调用servletinit()方法,传入ServletConfig的引用

容器初始化一个servlet时,会为这个servlet创建一个唯一的ServletConfig,容器从DD中读出servlet初始化参数,并把这些参数交给ServletConfig,然后把ServletConfig传递给servletinit()方法。

初始化参数:在web.xml配置文件中的<servlet>标签中

                   <init-param>

                      <param-name>adminEmail</param-name>

                      <param-value>zzq_rj@163.com</param-value>

        </init-param>

       servlet中调用:getServletConfig().getInitParameter(“adminEmail”);

b)      ServletContext对象

每个Web应用才有一个ServletContext,用于访问Web应用参数。Web应用中的各个servletJSP都能访问ServletContext

初始化参数:在web.xml配置文件中的<web-app>标签中<servlet>标签外

                  <context-param>

                      <param-name>contextname1</param-name>

                      <param-value>contextvalue1</param-value>

           </context-param>

servlet中调用:getServletContext().getInitParameter(“adminEmail”);

           或者   ServletContext context=getServletContext();

                context.getInitParameter(“adminEmail”);

JSP中调用:

 

15.    使用响应

通常,使用响应只是向客户发回数据,会调用两个方法:setContentType()getWriter()。当然,还可以使用响应设置其它首部、发送错误以及增加cookie

response.setContentType(“application/jar”);

完成I/O

ServletContext ctx=getServletContext();

InputStream is=ctx.getResourceAsStream(“/book.jar”);//必须以“/”开头,表示Web应用的根。

两种输出方式

字符形式:PrintWriter writer=response.getWriter();

         writer.println(“some text and HTML”);

字节流形式: ServletOutputStream out=response.getOutputStream();

            out.write(aByteArray);

16.    请求分派和重定向

a)      请求分派

RequestDispatcher view=request.getRequestDispatcher(“***.jsp”);// JSP 实例化一个请求分派器

view.forward(request response);// 使用请求分派器要求容器准备好 JSP ,并向 JSP 发送请求和响应

b)      重定向

response.sendRedirect(“URL”);

其中 URL 是相对的 URL ,有两种类型:前面有斜线和没有斜线

例: 客户原来的请求是   http://www.wick.com/myApp/cool/bar.do ,请求到达名为“ bar.do ”的 Servlet 时,该 Servlet 中会基于一个相对的 URL 来调用 sendRedirect() 。 不带斜线: sendRedirect(“foo/stuff.html”); 容器会相对于原先的请求 URL 建立完整的 URL ,即   http://www.wick.com/myApp/cool/foo/stuff.html

带斜线的: sendRedirect(“/foo/stuff.html”); 容器会相对于 Web 应用本身建立完整的 URL ,而不是相对于原来的请求 URL ,即: http://www.wick.com/foo/stuff.html

    请求分派是在服务器端发生,浏览器地址上的 URL 没有改变 ( 相当于被请求的 Servlet 把请求传递给服务器上的另一个组件,而客户并不知道 ) ;重定向是在客户端进行,用户会在浏览器地址栏中看到新的 URL( 相当于服务器又告诉浏览器去访问另一个 URL)

 

17.    HttpSession

http://www.blogjava.net/cheneyfree/archive/2007/05/26/120168.html

可以跨多个请求保存会话状态,与一个特定可和的整个会话期间, HttpSession 对象会持久存储。

在响应中发送一个会话:

HttpSession session=request.getSession();// 等价于 request.getSession(true)

//HttpSession session=request.getSession(false); 返回一个已经存在的会话,如果没有与此客户相关联的会话,返回 null

    Web 容器会自己生成会话 ID 、建立新的 Cookie 对象、把会话 ID 放到 cookie 中、在响应中设置 Cookie set-Cookie )首部。在后续的请求中,容器会从请求中的 cookie 得到会话 ID ,将这个 ID 与一个现有的会话匹配,并把会话与当前请求关联。

    如果用户浏览器禁止使用 Cookie ,则在客户的请求首部中就不会含有 ID Cookie 。这时可重写 URL 让客户和容器交换会话 ID 信息。容器总是默认地先使用 cookie ,如果 cookie 不能工作,容器就会求助于 URL 重写。 URL 重写是自动的,但是必须对 URL 完成了编码它才凑效。如:

out.println(“<a href=\””+response.encodeURL(“/beerTest.do”)+”\”>click </a>”)

重新定向时对 URL 的重编码: response.encodeRedirectURL(“/beerTest.do”);

URL 编码只与响应有关,不能在请求中和上下文调用这个方法。

 

URL重定向是服务器自动完成的,对开发人员来说是透明的。(经测,iteye使用Cookie保存用户通行证的,禁用Cookie后,iteye登陆后,无法正常访问)

 

    实验步骤:

 

    1.两个页面 hello1.jsp,hello2.jsp

Java代码 复制代码  收藏代码
  1. hello1.jsp  
  2.   
  3. <body>  
  4.    <%  
  5.     String num ="100";  
  6.     session.setAttribute("num",num);  
  7.     //String url =response.encodeUrl("hello2.jsp");  
  8.     //String url =("hello2.jsp");      
  9.     %>  
  10.     <a href=<%=url%>>hello2.jsp</a>   
  11.  </body>  
  12.   
  13. hello2.jsp  
  14.   
  15. <body>  
  16.   <%=session.getAttribute("num")%>  
  17. </body>  
hello1.jsp

<body>
   <%
   	String num ="100";
	session.setAttribute("num",num);
	//String url =response.encodeUrl("hello2.jsp");
	//String url =("hello2.jsp");    
	%>
	<a href=<%=url%>>hello2.jsp</a> 
 </body>

hello2.jsp

<body>
  <%=session.getAttribute("num")%>
</body>

    浏览器Cookie禁用,

    打开hello1.jsp中的String url=response.encodeUrl("hello2.jsp");注释

    访问http://localhost:8080/SessionTest/hello1.jsp,点击hello2.jsp

    会跳转至hello2.jsp,浏览器地址栏显示为:

    http://localhost:8080/SessionTest/hello2.jsp;jsessionid=85227A80E09D4443B0A037576B3270AF

    页面结果显示为 100

 

    关闭hello1.jsp中的String url=response.encodeUrl("hello2.jsp");打开String url="hello2.jsp";注释

    访问http://localhost:8080/SessionTest/hello1.jsp,点击hello2.jsp

    会跳转至hello2.jsp,浏览器地址栏显示为:

    http://localhost:8080/SessionTest/hello2.jsp

    页面结果显示为 null

 

    2.  新建测试页面index.jsp、test.jsp和SessionTestServlet.java

Java代码 复制代码  收藏代码
  1. index.jsp页面  
  2.   
  3. <body>  
  4.    <a href="servlet/SesstionTest?userName=zzqrj">test1</a>  
  5.  </body>  
  6.   
  7. SessionTestServlet.java  
  8.   
  9. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  10.             throws ServletException, IOException {  
  11.   
  12.         response.setContentType("text/html");  
  13.         PrintWriter out = response.getWriter();  
  14.   
  15.         String userName = request.getParameter("userName");  
  16.         HttpSession session = request.getSession();  
  17.         session.setAttribute("userName", userName);  
  18.         //String url=response.encodeRedirectUrl("../test.jsp");  
  19.         //String url="../test.jsp";  
  20.         System.out.println(url);  
  21.         response.sendRedirect(url);  
  22.         //RequestDispatcher view=request.getRequestDispatcher(url);  
  23.         //view.forward(request, response);  
  24. }  
  25.   
  26. test.jsp  
  27.   
  28. <body>  
  29. <%=session.getAttribute("userName") %>  
  30.    <a href="<%=response.encodeUrl("servlet/SesstionTest") %>">test1</a>  
  31. </body>  
index.jsp页面

<body>
   <a href="servlet/SesstionTest?userName=zzqrj">test1</a>
 </body>

SessionTestServlet.java

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		String userName = request.getParameter("userName");
		HttpSession session = request.getSession();
		session.setAttribute("userName", userName);
		//String url=response.encodeRedirectUrl("../test.jsp");
		//String url="../test.jsp";
		System.out.println(url);
		response.sendRedirect(url);
		//RequestDispatcher view=request.getRequestDispatcher(url);
		//view.forward(request, response);
}

test.jsp

<body>
<%=session.getAttribute("userName") %>
   <a href="<%=response.encodeUrl("servlet/SesstionTest") %>">test1</a>
</body>

    测试方法同1,结果也同1.

    3. 打开浏览器Cookie,分别对1,2中的页面进行测试

    不管是String url=response.encodeUrl("hello2.jsp");打开或是String url="hello2.jsp";打开,浏览器地址栏均不显示" ;jsessionid=***** "。并且结果页面总不为null。

 

18.    删除会话

a)      超时设置

程序: session.setMaxInactiveInterval(20*60);

// 改变特定会话实例的 session-timeout 值,不会影响应用中其他会话的超时时间。

DD 描述: 相当于在每个会话上调用 setMaxInactiveInterval() 方法

< session-config >

                < session-timeout > 15 </ session-timeout >   单位是分钟

        </ session-config >

b)      在会话对象上调用 invalidate() : session.invalidate();

c)      应用程序结束

 

19.    Cookie

 

Cookie 的作用

a)         支持会话状态 。

b)        可以使用 cookie 在服务器和客户之间交换名 / 值对 。

服务器把 cookie 发送给客户,客户再在以后的每个请求中把 cookie 发回,当客户的浏览器退出时,会话 cookie 会自动消失,但是可以设置 cookie 在客户端持久保存 。

使用 Cookie

1 )可以从 HTTP 请求和响应中得到与 Cookie 相关的首部 。

2 )利用 ServletAPI 使用 Cookie

        创建新 Cookie   Cookie  cookie=new Cookie(“username”,name);

        设置 cookie 在客户端存活时间: cookie.setMaxAge(30*60);

        cookie 发送到客户: response.addCookie(cookie);

        从客户请求得到 cookie

               Cookie[] cookies=request.getCookies();

               for(int i=0;i<cookies.length;i++){

       Cookie cookie=cookies[i];

       if(cookie.getName().equals(“username”)){out.println(cookie.getValue());}

}

 

20.        会话生命周期

 

21.        Servlet

是一种跨平台语言的服务器端技术, 采用 Servlet 开发的应用,不用考虑平台,多线程等让人头疼的问题,使得开发人员专注于业务逻辑的实现,大大解放了生产力。

Servlet 中嵌入 HTML 代码是开发人员的噩梦


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值