使用JSP/Servlet技术开发新闻发布系统

           第一章:动态网页开发基础 

动态网页:是指在 服务器端运行的,使用程序语言设计的交互式网页,它们会根据某种条件的变化,返回不同的网页内容
动态网页需要使用服务器端的脚本语言,例如:JSP技术就是使用Java+HTML
动态网页的优势:
1:交互性:
      网页会根据用户的要求和选择而动态改变和显示内容
2:自动更新:
      无须改变页面代码,便会自动生成新的页面内容,可以大大节省工作量
3:随机性:
    当不同的时间、不同的人访问同一网址时会产生不同的页面效果
     例如:普通用户和管理员登录论坛时看到的页面效果内容是不同的
B/S(Browser/Server)架构技术
QQ聊天软件就是一个典型的C/S(Client/Server)
基于B/S架构的Web应用程序由于不再受安装客户端的限制,访问及其简便,因此被越来越多的企业采用,在此需要特别说明的是B/S架构的出现不是对C/S架构的一种变化或者改进。
B/S架构是随着Internet技术的兴起,对C/S架构的一种改进而非C/S的替代品
B/S架构的优势:维护和升级方式简单
B/S架构中,软件应用的业务逻辑完全在服务器端实现所有的客户端只是浏览器,不需要做任何的维护。因此系统管理员只需要关注服务器的软件升级即可。客户端只要重新登录系统,使用的就是最新版本的软件了
B/S架构的劣势:在速度和安全性上需要花费巨大的设计成本。
而且由于B/S架构的交互式请求/响应的模式,一旦数据信息发生变化,必须要通过刷新页面,才能看到更新的数据信息
什么时候用C/S?
C/S一般面向相对固定的用户群,一般高度机密的信息系统采用 C/S架构
如:企业内部的信息管理系统,金融证券管理系统
什么时候用B/S?
B/S适用于公开信息发布,对信息的保密性要求较低,如企业网站、售后服务系统等

B/S架构的工作原理

只有浏览器解释执行完HTML文件,才能呈现结果界面
URL(Uniform Resource Locator)统一资源定位符
HTTP:(Hyper Text Transfer Protocol)超文本传输协议  Transmisstion
百度ip:202.108.22.5但常常使用它的域名baidu.com

Tomcat端口号的配置
在Tomcat目录下找到子目录conf------server.xml
用ctrl+f 查找 Connector port="8080",其中8080可改为6060修改后重新启动Tomcat目录结构

Web目录结构

在Tomcat的运行过程中,Tomcat类加载器会首先加载classes目录下的class文件,然后再加载lib目录下的类,需要注意的是,如果在classes目录下和lib目录下存在同名的类,那么classes目录下的类具有优先权
每个java web 应用都有一个核心文件,即web.xml,此文件必须保存在web-inf目录下,因为该目录客户端不可访问,他控制整个应用的行为和方法
   配置web起始访问页面:
在web.xml文件中
 <welcome-file-list>
    <welcome-file>index.jsp---(这里可以改成html文件)welcome-file>
  welcome-file-list>  

webapps目录用于进行web项目的发布





实现动态网页的关键就在于运行在服务器端的脚本语言
jsp的优点是:跨平台,易维护,易管理
实际上jsp就是在html中嵌入java的脚本语言
jsp的执行步骤:
翻译:成java源文件
编译:java源文件编译成class文件:二进制字节码文件
运行:class文件
当第二次发生相同的jsp请求时,就可以直接运行class文件
,所以JSP第一次请求时会比较慢,后续会很快
jsp页面由静态内容、指令、表达式、小脚本、
声明、标准动作、注释等元素构成
静态内容:即HTML文本
日期在java.text.*包中;
<%=
  //有等号的的表示数据,不能写分号,相当于打印的功能
  //使用预定格式将日期转换为字符串
     new SimpleDateFormat("yyyy年MM月dd日HH点").format(new Date())
   %>  
<%! 
    //!表示声明,可以声明成员变量,也可以声明方法----声明方法时必须要有声明符!  
    String declare="this is a declare";
    public static void main(String args[]){
    
    }
 %>   

如果要想知道程序是怎么运行的,因为JSP页面已经翻译成了.java文件,所以我们可以到Tomcat目录下的work目录
(这个目录存放着各个web 应用的servlet 即 java和class文件)


-----------

<%-- 这是JSP注释代码,客户端 不可以 通过浏览器的右键查看源代码看到注释的代码 --%>
<%
    //java单行注释
    /*多行注释*/
    /** 
     文档注释
    */
 %>  
<% %>是在_jspService()这个方法内部进行编码   属于局部变量
<%! %>是在jsp的class类里面进行编码   属于类的成员

JSP的脚本元素包括:表达式、小脚本、声明
 <% %>//这个叫小脚本
  <%= %>//这个叫表达式,表达式的等号和分号不能同时存在,否则就会编译错误!  
<%!  %>//这个叫声明
JSP指令元素
JSP指令元素的作用是通过设置指令中的属性,在JSP中运行时,控制jsp页面的某些特性:<%@   %>
<%@ page language="java" import="java.util.*,com.accp.epet.dao.*,com.accp.epet.entity.*" pageEncoding="UTF-8"%>  
_______
contentType=" text/html;charset=utf-8"  等同于 pageEncoding ="UTF-8"
page 指令是针对当前页面进行设置的一种指令,通常位于jsp页面中的顶端。需要注意的是,page指令只对当前jsp页面有效,但是一个jsp页面中可以包含多个page指令

page指令常用的属性: 
language:指定当前页面所用的脚本语言 <%@  page language="java"  %>  
import:导入java的包
contentType:默认是 " text/html ; charset= ISO-8859-1 "
让每次新建的jsp文件默认的编码是UTF-8


                                                      第二章:JSP数据交互




Validate:验证
Context:上下文
Request:请求  :当前请求(别的请求无效)
Response:响应
Redirect:重定向
Session:会话:当前会话 (可以包含多个请求)在该会话有效期内可以访问
Application:当前服务器(可以包含多个会话):
当服务器启动后就会创建一个application对象,被所有用户共享
page、request、session、application四个作用域对象都有
setAttribute()和getAttribute()方法
而且作用域范围越来越大


1:request对象

是从客户端向服务器端发出请求,包括用户提交的信息以及客户端的一些信息。request对象是javax.servlet.http.HttpServletRequest类的实现实例。

request对象封装了浏览器的请求信息,通过request对象的各种方法可以获取客户端以及用户提交的各项请求信息。

使用request对象获取客户端提交的请求参数的常用方法如下:

1.String getParameter(String name),获取上一页面所提交的参数值的参数值,并以字符串形式返回指定参数的值,如果参数不存在则返回空值。用于表单、链接或网址栏传递参数时,使用此方法。

例如,获取客户端name的参数值:

String name = request.getParameter("name");

2.String[ ] getParameterValues(String name),获取以相同名称命名的表单组件提交的数据,主要用于获取复选框的值,返回值类型是字符串数组String[ ]

例如,获取客户端hobby复选框的所有取值:

String[ ] hobbys = request.getParameterValues("hobby");
       if(hobbys != null)
       {
       out.println("您的爱好有:");
       for(int i=0;i
          out.println(hobbys[i]);
       }

3.void setCharacterEncoding(String encoding),设置字符编码方式,用来解决传递非英文字符所出现的乱码问题。

对于以post提交的表单数据

在第一行写:
request.setCharacterEncoding("UTF-8");

对于以get提交的表单数据

提交的数据作为查询字符串被附加到URL 的末端发送到服务器,此时字服务器端调用

setCharacterEncoding()方法就没有作用了,我们需要得到请求参数值之后,进行编码转换

String name=request.getParameter("name");

name=new String(name.getBytes("ISO-8859-1"),"UTF-8"); 
也可以通过TomCat目录下的conf下的server.xml文件,在元素中添加URIEncoding 属性,将它的值设置为“utf-8”

    port="8080"

    protocol="HTTP/1.1"

     reidrectPort="8433"

    URIEncoding ="UTF-8"

/>

4.RequestDispatcher getRequestDispatcher(String path)----获取请求分配器

返回一个javax.servlet.RequestDispatcher对象该方法的forward()方法用于 转发请求

例如,request.setCharacterEncoding("UTF-8");

实例:使用request对象实现用户注册功能

zhuce.html源代码如下:



  
    个人信息注册
 
    
    
    
   
    

  
 
  
    

个人信息注册


    <form action="zhuce.jsp" method="post">
        姓名:

        密码:

        请选择你的职业:
        农民
     工人
     学生
     教师
     

     你喜欢的城市:
     
     

     请选择你的爱好:
     旅游
     看书
     游戏
     琴棋书画
     

     自我介绍:
     
     

     
    
  

zhuce.jsp源代码如下:

<%@ page language="java" import="java.util.*" contentType="text/html;charset=UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



  
    
   
    个人信息注册
   

  
 
  
    <%request.setCharacterEncoding("UTF-8"); %>
     您的姓名是:<%=request.getParameter("name") %>

     您的密码是:<%=request.getParameter("pwd") %>

     您的职业是:<%=request.getParameter("career") %>

     您喜欢的城市是:<%=request.getParameter("city") %>

     您的爱好有:<%String[] hobbys = request.getParameterValues("hobby");
       if(hobbys != null)
       {
       out.println("您的爱好有:");
       for(int i=0;i
          out.print(hobbys[i]);
       }
      %>
      

     自我介绍:<%=request.getParameter("intro") %>

  

2:response对象
常用方法:
void addCookie(Cookie cookie):在客户端添加cookie
void sentRedirect(String location);重新定位到新的URL


getRequestDispatcher()与sendRedirect()的区别

1.request.getRequestDispatcher()是请求转发,前后页面共享一个request ; 
response.sendRedirect()是重新定向,前后页面不是一个request。

2.RequestDispatcher.forward()是在服务器端运行; 
HttpServletResponse.sendRedirect()是通过向客户浏览器发送命令来完成. 

3.ServletContext.getRequestDispatcher(String url)中的url只能使用绝对路径; 而

ServletRequest.getRequestDispatcher(String url)中的url可以使用相对路径。因为

ServletRequest具有相对路径的概念;而ServletContext对象无此概念。

RequestDispatcher对象从客户端获取请求request,并把它们传递给服务器上的servlet,html或

jsp。它有两个方法:


2.void include(ServletRequest request,ServletResponse response) 
用来记录保留request和response,以后不能再修改response里表示状态的信息。

 

二者区别: 
response.sendRedirect(url)跳转到指定的URL地址,产生一个新的request,所以要传递参数只有在url后加参 
数,如: 
url?id=1. 
request.getRequestDispatcher(url).forward(request,response)是直接将请求转发到指定URL,所以该请求
 
能够直接获得上一个请求的数据,也就是说采用请求转发,request对象始终存在,不会重新创建。而 
sendRedirect()会新建request对象,所以上一个request中的数据会丢失。 
更具体来说就是这样的: 
redirect 会首先发一个response给浏览器, 然后浏览器收到这个response后再发一个requeset给服务器, 然后 
服务器发新的response给浏览器. 这时页面收到的request是一个新从浏览器发来的. 
forward 发生在服务器内部, 在浏览器完全不知情的情况下发给了浏览器另外一个页面的响应. 这时页面 
收到的request不是从浏览器直接发来了,可能己经用request.setAttribute在request里放了数据.在转到的页 
面可直接用request.getAttribute获得数据。 




重定向的重要应用:

使用重定向技术实现超链接的数据传递
<a href="color.jsp?color=黄色">黄色a>  

使用超链接进行数据传递时,采用的是get方式提交请求, 如果在传递数据中存在中文, 就会造成乱码,因为request.setCharacterEncoding("utf-8")只适用于post方法提交  所以可以通过 设置tomcat字符集实现
当传递多个数据时,可以用&连接
<a href="color.jsp?color=黄色&id=1">黄色a>   

Session
//设置10分钟后失效
session.setMaxInactiveInterval(10*60);  
也可以在项目的web.xml中设置  代码片段如下:
    30       ------这里的单位是分钟  系统默认会话超时是30分钟  0表示失效   -1表示永不超时

使整个session会话失效:session.invalidate();
如果只想清空session的某个对象 ,则可以调用session.removeAttribute(String key)方法,将指定的对象从session中清除
此时session对象仍然有效
1、概念:Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的。在Servlet中,session指的是HttpSession类的对象,这个概念到此结束了,也许会很模糊,但只有看完本文,才能真正有个深刻理解。
 
2、Session创建的时间是:
JSP文件在编译成Servlet时将会自动加上这样一条语句 HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的 session对象的来历。
由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。
 
引申:
2)、当JSP页面没有显式禁止session的时候,在打开浏览器第一次请求该jsp的时候,服务器会自动为其创建一个session,并赋予其一个sessionID,发送给客户端的浏览器。以后客户端接着请求本应用中其他资源的时候,会自动在请求头上添加:
Cookie:JSESSIONID=客户端第一次拿到的session ID
这样,服务器端在接到请求时候,就会收到session ID,并根据ID在内存中找到之前创建的session对象,提供给请求使用。这也是session使用的基本原理----搞不懂这个,就永远不明白session的原理。
下面是两次请求同一个jsp,请求头信息:
通过图可以清晰发现,第二次请求的时候,已经添加session ID的信息。
 
3、Session删除的时间是:
1)Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。
2)程序调用HttpSession.invalidate()
3)服务器关闭或服务停止
 
4、session存放在哪里:服务器端的内存中。不过session可以通过特殊的方式做持久化管理。
 
5、session的id是从哪里来的,sessionID是如何使用的:当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象,当浏览器下次(session继续有效时)请求别的资源的时候,浏览器会偷偷地将sessionID放置到请求头中,服务器接收到请求后就得到该请求的sessionID,服务器找到该id的session返还给请求者(Servlet)使用。一个会话只能有一个session对象,对session来说是只认id不认人。
 
6、session会因为浏览器的关闭而删除吗?
不会,session 存在于服务器内存中

ServletContext application=this.getServletContext();
            List listUser = (List)application.getAttribute("currentListUser");
            if(listUser == null){
                listUser = new ArrayList();
            }
            listUser.add(user);
            application.setAttribute("currentListUser", listUser);  

page作用域:
   在服务器发送响应或请求转发其它页面或资源后无效
   pageContext对象本身也属于page作用域,具有page作用域的对象被绑定到pageContext对象中
request作用域:
session作用域:
    一个浏览器窗口对应一个session对象,当新开一个浏览器窗口时,会重新创建一个session对象
application作用域:


Cookie:
cookie是由Netscape公司发明的,最常用的跟踪用户会话的方式。它
是由服务器端生成,发送给客户端浏览器的,浏览器会将其保存为某一
个目录下的文本文件,方便下一次请求
cookie的作用:
》》》对特定对象的跟踪:如访问者的访问次数,最后访问时间,路径
》》》统计网页浏览次数
》》》在cookie有效期内,记录用户登录的信息
》》》针对用户的喜好推荐不同的内容
 <%
     //javax.servlet.http.Cookie这个包,当JSP翻译成.java文件时会自动导入
          Cookie c=new Cookie("pwd","123");
          c.setValue("456");
     %>
        <%=
           //c.getMaxAge()----  -1  永不超时 c.setMaxAge(0); 0表示失效
           // c.getPath()----null
           //c.getVersion()---0
          //c.getSecure()//cookie是否安全
        //  c.getName()//只有getName()没有setName(),因为名字不可改
          c.getValue()
         %>  
如果未向cookie中添加数据,当创建session时,sessionid的值cookie的值是一样的,说明sessionid被保存在cookie中
当服务器对一个请求作出处理时,cookie才会被写入客户端
使用setMaxAge(int expiry)时,有以下几种情况:
通常情况下expiry为大于0的整数,表示cookie的有效存活时间
如果设置expiry参数等于0,表示删除cookie
设置expiry参数为负或者不设置,表示cookie会在当前窗口关闭后失效
cookie用于保存不重要的用户信息,重要的用户信息使用session保存
 <%
         response.addCookie(new Cookie("uname","Jack"));
         response.addCookie(new Cookie("pwd","123"));
         response.sendRedirect("look.jsp");
      
       %> 

look.jsp
<%
   Cookie[] cookie=request.getCookies();
   String uname=null;
   String pwd=null;
   if(cookie==null){
   out.println("用户名:"+uname+"  "+"密码:"+pwd);
       return;
   }
   
   for(Cookie c:cookie){
       if(c.getName().equals("uname")){
             uname=c.getValue();
       }else if(c.getName().equals("pwd")){
              pwd=c.getValue();
       }
  } 
   out.println("用户名:"+uname+"  "+"密码:"+pwd);
%> 











                            第五章:使用分层实现业务处理
JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。现在JNDI已经成为J2EE的标准之一,所有的J2EE容器都必须提供一个JNDI的服务。
JNDI可访问的现有的目录及服务有:
DNS、XNam 、Novell 目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA 对象服务、文件系统、Windows XP/2000/NT/Me/9x的 注册表、RMI、DSML v1&v2、NIS。数据库
Tomcat 根目录\conf\context.xml文件为全局的上下文配置文件,对所有的Web应用有效。所以将要发布的信息配置在此问件中,再通过JNDI来查找信息
    ---我们可以在Tomcat中发布一条信息,修改context.xml
   
            
                 
           
type:java类名的全称
name:变量名,相对于java:comp/env的路径
value:变量值
 数据库连接池的配置:
(第一步:)
 
  type="javax.sql.DataSource" maxActive="100"
  maxIdle="30" maxWait="10000"
  username="sa" password="123456"  
          url="jdbc:sqlserver://localhost:1433;DatabaseName=NewsManagerSystem"                      
  driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
/>
       contextName

     name

    ....

 

     name

     Kitty

 

2//加载顺序排第二



java中含义
    java中的load-on-startup用于表示该servlet是否在servlet容器启动的时候加载。
示例:>xx
其中:如果xx是负数或者其他数值或者没有指定,表示该servlet在被选择时才加载;
      如果xx为正数或者为0,表示在servlet容器启动的时候就加载,而且数值越小,加载的优先级越高!

注意:有些初始值需要servlet容器在启动的时候就应该加载到内存中,所以很有必要设置这些初始值在启动的时候就应该加载,这种情况下就可以设置这个servlet的load-on-startup属性


Servlet在编译的代码之外有初始化参数,当参数改变时,不需要重新编译Servlet  ,每个servlet都有一个与之相联的对象ServletConfig; (在servletConfig对象中包含了servlet的初始化参数信息。)

得到指定的参数value:String value= getServletConfig().getInitParameter(“name"); 

也可以这么写:String value= this.getInitParameter(“name"); //this可省

得到所有的所有的参数value:需要应用一个ServletConfig中的一个方法:getInitParameterNmes():返回一个Enumeration(枚举)对象,里面包含了所有的初始化参数。

 

  1. Enumeration e = this.getServletConfig().getInitParameterNames();  
  2.         while(e.hasMoreElements()){  
  3.             String name = (String)e.nextElement();  
  4.             String value = this.getServletConfig().getInitParameter(name);  
  5.             System.out.println(name+"="+value);  
  6.         }  
  7.     }  
 获得上下文参数:
String value=this.getServletContext().getInitparameter("contextName");

  1. import java.io.IOException;  
  2. import java.io.PrintWriter;  
  3. import java.util.Enumeration;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. /**  
  10.  * 获取Http协议的请求行,请求头  
  11.  * @author Starjuly  
  12.  *  
  13.  */  
  14. public class RequestDemo1 extends HttpServlet {  
  15.   
  16.        
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         System.out.println("请求行的方法:" + request.getMethod());  
  20.         System.out.println("请求行的URI:" + request.getRequestURI());  
  21.         System.out.println("请求行的URL:" + request.getRequestURL());  
  22.         System.out.println("请求行的版本:" + request.getProtocol());  
  23.           
  24.         System.out.println("请求头:"+request.getHeader("User-Agent"));  
  25.         //利用迭代器遍历所有的请求头  
  26.         Enumeration names = request.getHeaderNames();   
  27.         while(names.hasMoreElements()){  
  28.             //获取请求头  
  29.              String  nextElement = (String)names.nextElement();  
  30.              //获取每个请求头的内容  
  31.              String header = request.getHeader(nextElement);   
  32.              System.out.print(nextElement+" : ");  
  33.              System.out.println(header);  
  34.         }  
  35.           
  36.     }  
  37.   
  38.        
  39.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  40.             throws ServletException, IOException {  
  41.   
  42.         doGet(request,response);  
  43.     }  
  44.   
  45. }  

ServletContext 应用上下文:
 
属于整个Web应用程序
可以访问到Web应用程序资源的本地输入流
把资源的虚拟路径转换为物理路径
记录事件日志
绑定一个对象在整个Web应用程序中共享
 
初始化web应用程序参数:

 

 …

 

     admin email

     [email protected]

 

     …

 

在Servlet中共享信息

为所有的Servlet设置一个实时变化的参数值
在Web应用程序中共享一个对象
eg:

servletContext.setAttribute("password", "tiger");

String password = (String) servletContext.getAttribute("password");

虚拟路径转换为物理路径:

getResourcePaths(java.lang.String path):返回一个集合,路径必须从Web应用程序的根“/”开始;

getResourceAsStream(java.lang.String path):返回一个InputStream对象。当一个资源需要逐字节读取的时候该方法比较适用。

getResource(java.lang.String path):返回一个Web资源列表。



Servlet与jsp 的区别:
JSP在本质上就是Servlet,但是两者的创建方式不一样.Servlet完全是JAVA程序代码构成擅长于流程控制和事务处理而通过Servlet
来生成动态网页;JSP由HTML代码和JSP标签构成,可以方便地编写动态网页
因此在实际应用中采用Servlet来控制业务流程,而采用JSP来生成动态网页.在struts框架中,JSP位于MVC设计模式的视图层,而Servlet位于控制层.
答案2:
JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。




回顾上一章的知识:
Java Servlet是运行在Web服务器或应用服务器上的Java程序
Servlet规范对Servlet功能进行了严格定义
Servlet API与容器进行通讯
Servlet的编码和部署
Servlet需要在容器中进行注册和映射
容器管理Servlet的生命周期
SevletConfig对象为Servlet提供初始化参数
ServletContext对象属于整个Web应用程序
 
本章学习知识:
回顾HTTP请求的处理过程(回顾第一章)
设置HTTP状态码
设置HTTP响应头
设置HTTP消息体
请求重定向和自动刷新页面
 

设置HTTP状态码

设置响应状态行:
HTTP状态码:

HTTP状态码:

100-199:表示信息性代码,标示客户端应该采取的其他动作,请求正在进行。

200-299:表示客户请求成功。

300-399:表示用于已经移走的资源文件,指示新的地址。

400-499:表示由客户端引发的错误。

500-599:表示由服务器端引发的错误

servlet设置状态码一般使用HttpServletResponse的setStatus()方法;

设置HTTP响应头

HttpServletResponse对象用于操纵响应的HTTP头
目的用于告诉客户端
–发送回来的内容的类型
–有多少内容正被发送
常用的方法:

setContentType(String mimetype);

addCookie(Cookie c);

发送内容的服务器的类型

设置HTTP消息体

HttpServletResponse对象负责将信息返回给客户端

HttpServletResponse对象只产生一个空的HTTP响应

传回自定义的内容需要使用getWriter()或者getOutputStream()方法

–传送普通文本

–传送二进制内容 

 

请求重定向和自动刷新页面

重定向的原理:(看三张图片):

         

            

          

使用sendRedirect(String URL)方法实现重定向,

 

在指定时间内自动刷新当前页或到一个新的页面
根据时间来控制响应
想在响应中有一个短时间的暂停 

response.setHeader("Refresh", "time; URL=url" );

 总结:
请求URL时HTTP发出了多个请求
状态码告诉浏览器发送的内容及格式状态
Servlet API与容器进行通讯
HttpServletResponse定义的常量来避免直接使用整数
在通过PrintWriter对象发送任何内容之前先调用 HttpServletResponse的setStatus()方法
为了让Servlet发挥最大的效能,HttpServletResponse对象用于操纵响应的HTTP头
getWrite()或者getOutputStream()方法传送文本或者二进制内容给客户端
sendRedirect方法实现重定向
HTTP响应头“Refresh”会根据时间来控制响应

回顾上一章的知识:
请求网络资源HTTP会发出多个请求并得到响应
设置响应状态行关键是设置状态码
在向客户端输出内容之前要设置状态码和响应头
设置响应头让Servlet发挥最大功能
消息体可以用文本或二进制流方式发送
响应重定向把请求转发给另外一个URL,利用302状态码和Locatoin头,让浏览器处理
可以根据时间来控制响应
 
本章目标:
HTTP请求提交的方法
获取HTTP请求行与请求头
获取表单数据
请求派发和请求范围
 
GET/POST提交方法:
浏览器向Web服务器发送HTTP请求
–用户在网页上点击一个超连接
–用户提交在网页上填写好的表单
–用户在浏览器地址栏中输入URL地址并回车 
默认情况下都是使用HTTP协议的GET方法提交请求
 
GET/POST提交方法区别:
 

何时使用GET/POST方法:

1:请求一个静态页面或图形文件时使用GET方法,因为仅仅需要发送文件名;

2:发送大数据的时候,使用POST方法;

3:上传文件时,使用POST方法;

4:发送用户名、密码或其他保密信息的时候使用POST方法;
 
获取HTTP协议请求行:
HttpServletRequest对象的如下方法访问
–getMethod():获取HTTP的请求方法,例如GET、POST等

-getRequestURI():获取请求的URI资源

–getRequestURL():获取请求的URL,包含协议名、服务器名或IP、端口号和请求资源但不包括查询字符串参数
–getQueryString():获取请求URL后面的查询字符串
–getProtocol():获取HTTP的协议名和版本号
–getContextPath():获取请求URI资源的上下文路径
–getServletPath():获取Servlet的映射路径
 
获取HTTP协议请求头:
HTTP请求头用于告诉服务器客户端使用什么软件以及客户端想要服务器如何返回请求的信息
HttpServletRequest对象的如下方法访问
–getHeader(name):返回指定的请求头的值
–getHeaders(name) :返回一个Enumeration(枚举)包含请求头中的所有值
–getHeaderNames():特定请求中接受到的所有请求头的名称
–getIntHeader(name):获取特定请求头的值,并将其转化为int类型
–getDateHeader(name):获取特定请求头的值,并将其转化为Date类型  
 

Enumeration enum = request.getHeaderNames();

      while (enum.hasMoreElements()) {

          String headerName = (String) enum.nextElement();

         String headerValue = request.getHeader(headerName);

        out.print(""+headerName + ": ");

        out.println(headerValue + "
");

      }

 

获取请求消息体:

消息体可以是普通文本也可以是二进制数据 
HttpServletRequest对象可以使用通用的方法来获取表单数据
 
请求转发和请求方法:
重定向和请求转发之间最大的区别在于,重定向让客户端浏览器来完成,而请求转发是在服务器端做工作。
请求转发:
RequestDispatcher对象可以通过调用ServletRequest对象的方法:getRequestDispatcher(String path);
RequestDispatcher对象提供了两种方法来包含资源以及请求转发到不同的资源:
forward(ServletRequest, ServletResponse):派发请求和响应对象到RequestDispatcher 对象所确定的新资源(Servlet、JSP或者HTML等)
include(ServletRequest, ServletResponse):该方法关键是能包含服务器端的资源 
总结:
HttpServletRequest对象主要用于处理分析请求
默认情况下,使用HTTP协议的GET方法提交请求
HTML表单通过“method”属性使浏览器使用HTTP POST方法
GET/POST方法适用于不同场合
HttpServletRequest对象中最常用的方法是获取请求表单参数
HttpServletRequest对象也可以得到请求中参数的原始字节数据
重定向和请求派发之间最大的区别在于,重定向让客户端浏览器来完成,而请求派发是在服务器端做工作
HttpServletRequest可以把一个对象用名字绑定在请求范围内,并且进行访问和删除

状态管理概述
Cookie
Session
URL重写
 
状态管理概述:
HTTP协议使用的是 无状态的连接
对容器而言,每一个请求都来自于一个新的客户
这里我们有四种方法来解决这个状态:
a:表单隐藏字段
b:Cookie
c:  Session
d:  URL重写
 
我们就来一一介绍这四种方案:
A:状态管理解决方案-表单隐藏字段
   表单隐藏字段:

1:对用户在网站上的访问进行会话跟踪。

2:为服务器端程序提供预定义的输入。

3:存储动态产生的页面上下文信息。  

隐藏字段存在一个主要的缺点,即只有每当每个页面都是动态生成的时候才有效。

 

 

B:表单是在生成动态时才有效,那么我们就使用HTTP Cookie来固定的保存在某个地方,需要是读取。

 

使用HTTP Cookie可以很好的维护和保留用户的状态信息,但是Cookie涉及到一些敏感的隐私问题,一些用户会禁用Cookie,这时我们需要另一个方法来解决

 

C:URL重写

 

D:Servlet提供了出色的解决方案,HttpSessionAPI,这种高级接口建立在Cookie和URL重写之上。

把客户的状态信息保存在服务器端

Session对象就是服务器为客户端创建并维护的用于存放客户状态数据的对象 

 

一:Cookie

1:Cookie原理:

服务器在响应请求时将一些数据以“键-值”对的形式通过响应信息保存在客户端,当浏览器再次访问相同的应用时,会将原先的Cookie通过请求信息带到服务器端。

Cookie cookie = new Cookie("cool", "tiger!");

response.addCookie(cookie); 

2:在Serlvet中管理Cookie

Servlet中提供了如下一系列操作Cookie的API
–Cookie(name, value):构造方法用于创建一个或多个Cookie
–setMaxAge(int lifetime):设置Cookie的过期时间(以秒为单位)。默认值为负值(Cookie将在浏览器关闭时过期)
–getMaxAge():获取Cookie的过期时间。
–getName():获取Cookie的名字
–setValue(String value):指定Cookie的值。
–getValue():获取Cookie的值
-.......
 
3:在Servlet中使用Cookie
要将Cookie发送到客户端,Servlet应该按照下列的操作步骤执行:
–创建一个或多个Cookie,使用构造方法指定Cookie的名字和值
–使用setXXX方法为Cookie设置属性值
–使用HttpServletResponse对象的addCookie()方法将Cookie插入到响应头中
要读取客户端传入的Cookie,Servlet执行下列操作步骤:
–使用HttpServletRequest对象的getCookie方法返回一个Cookie对象数组
–Servlet遍历该数组(调用getName()方法),直到找到与名称相匹配的Cookie值
 
 
 
二:Session
1:Session原理
-服务器可以为客户端创建并维护一个Session对象,用于存放数据。
-在创建Session对象的同时,服务器将会为该 Session对象产生一个唯一编号,这个编号称之为SessionID
-服务器以Cookie的方式将SessionID存放在客户端。
-当浏览器再次访问该服务器时,会将SessionID作为Cookie信息带到服务器,服务器可以通过该SessionID检索到以前的Session对象,并对其进行访问
 
2:Session工作流程
 
3:Session会话跟踪机制
 
用户发送请求

HttpSession session = request.getSession(); //getSession(false)方法使用已经存在的会话,而不必创建新会话

服务器的响应
再次发送请求
4:HttpSessoin接口
HttpSession接口常用的一些方法
–setAttribute(java.lang.String, java.lang.Object):在Session对象中用一个名字绑定一个对象。
–getAttribute(java.lang.String):通过名字获取Session对象中保存的对象。
–removeAttribute(java.lang.String):在Session中删除与一个名字对应的对象。
–getCreationTime():返回第一次创建会话的时间。
–getLastAccessedTime():返回容器最后一次得到该会话ID的请求时间。
–setMaxInactiveInterval(int interval):对于会话指定客户请求的最大间隔时间,以秒为单位。-1表示永不过期
–getMaxInactiveInterval(int interval):返回客户请求的最大间隔时间。
–invalidate():会话结束,当前存在在会话中的所有会话属性也会解除绑定。
–getId():此方法返回每个session唯一的标识 
-......
5:会话超时管理
销毁会话可以采用如下三种简单的方式           //浏览器关闭时并不意味着Session对象被删除
–设置会话超时。
–在Session对象上调用invalidate()方法。
–应用结束(崩溃或取消部署)
在web.xml文件中配置    //以分钟为单位

       15

   

 6:Session持久化管理

三:URL重写

Session对象的正常使用要依赖于Cookie
URL地址重写能够取得置于Cookie中的会话,并把会话ID附加到访问应用的各个URL最后

URL重写方法:

response.encodeURL()

response.encodeRedirectURL(“/lovobook/sucess.html” )

URL重写是容器自动完成的,但需要我们对URL进行编码才有效 

总结:

1 HTTP协议使用的是无状态的连接,连接只针对一个请求/响应
2 状态管理方案:表单隐藏字段、Cookie、Session、URL重写
3 Cookie是Web服务器发送到客户端浏览器并保存的简短文本信息
4 Session对象就是服务器为客户端创建并维护的用于存放客户状态数据的对象
5 用户会禁用Cookie。这时我们可以使用URL地址重写来解决
6 通过HttpServletResponse的addCookie方法将该Cookie信息添加到响应信息中
7 Session对象是某个Servlet调用HttpServletRequest.getSession()这样的语句时才被创建
8 Session对象是保存在服务器端,浏览器关闭时并不意味着Session对象被删除
9 Session只认SessionID不认人
10 应当尽量使用维护时间短的域对象
11 在向客户返回第一个响应时,会同时尝试设置Cookie和URL重写两种做法 


      
 EL(Expresstion Language)表达式和JSTL(JSP Standard Tag Library)


 <%
               Map map= new HashMap();
               map.put("one","java");
                request.setAttribute( "map" , map);//这句话一定要写,要不然EL获取不到
   %>
   学科:    ${map.one}  


如果map里放的是数字字符串,则在EL表达式的里不能通过 " ."操作符来获取值

只能通过[ ]操作符来获取值,否则会运行时出错














<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>  

<c:set   target="${provinceList[0]}" property="provinceName" value="林建辉" var="u" scope="application" >c:set>
 <c:out value="${provinceList[0].provinceName }" default="noUname" escapeXml="true">c:out>
//通过变量名获取值,如果变量名为空,则显示默认值
 <c:out value="${u}" default="noUname" escapeXml="true">c:out>  

Empty 操作符:

是一个前缀操作符,用于检测一个值是否为null或empty

例如:如果变量a不存在或者变量a 的值为空,则${empty a }  为true   
检查非空用${ not empty a }或 ${ ! empty  a }   

作用域的访问对象:当使用EL表达式访问某个对象时,应该指定查找范围,如

${requestScope.employee}

如果不指定就会按照page---》request---》session--》application

<c:set var="isLogin" value="${!empty sessionScope.user }">c:set>
  <c:if test="${isLogin }">
    //如果为真执行里面的内容
  c:if>  


相当于if --else 
 <c:choose >
    <c:when test="${!empty isLogin }">
    
    c:when>

    <c:otherwise>
    
    c:otherwise>
  c:choose>  

使用EL遍历Map集合

<%
    Map map=new HashMap();
    map.put("sssss","dddd");
    map.put("qqqqq","wwwwwww");
    map.put("aaaaaa","bbbbbbb");
    
         request.setAttribute("map", map);
  %>
    <%--一定要写${ } --%>
  <c:forEach var="entry" items="${map}">
        <%--充分说明map里有key属性和 value属性 --%>
      ${entry.key }---${entry.value}<br/>
  
  c:forEach>  








如果:定义了 var属性,则target属性会被禁止,包括property属性,而且JavaBean对象及property属性
不存在时不会报错

<c:set var="aa" value="2" target="javaBean" scope="request" property="name">c:set>
  <c:out value="${javaBean.name }">c:out>  

当没有指定var 变量时,target属性和scope属性不能同时存在,因为此时target对象是一个JavaBean对象  使用${requestScope.user},如果再定义scope属性的话会发生冲突





你可能感兴趣的:(jsp,servlet)