JSP相关知识点

一、概述:

  • JSP文件的后缀必须是*.jsp
  • JSP文件的文件名必须全部小写,如hello.jsp
  • JSP是在HTML页面的基础上发展而来的:JSP=HTML+Java代码。(所谓的JSP开发就是在HTML页面中嵌入大量的java代码)
    • 由于JSP页面中含有大量的java代码,所以单独的*.jsp页面是不能运行的,只有被部署在web container中的*.jsp才可以运行,因为JSP页面中的java代码需要被JDK编译、链接,需要运行在JRE中
    • JSP页面+web container=(html+java代码)+(web container+jdk)
    • *.jsp页面第一次被访问到时,执行速度(响应)会有点慢,因为该页面中的java代码的编译与链接需要时间
    • 访问已经被访问过的*.jsp页面时速度会变快,因为不需要再次编译JSP中的java代码了,直接执行其*.class文件即可
    • *.jsp每次被修改之后,都会重新编译一次其中的java代码
    • *.jsp之中的Java代码被编译、链接之后会生成*.java/*.class文件,这些文件会被放置在Tomcat安装目录的/work文件夹中,可以删除Tomcat安装目录下的整个work文件夹,删除之后,所有JSP文件中的java代码会被重新编译、链接,重新生成其对应的*.java/*.class文件,重新放置到Tomcat安装目录下的work文件夹下,以备下次访问该*.jsp文件时直接使用
  • JSP页面可以接收并使用HTML页面发送给自己的表单数据,具体实现方法如下:
    • step1,*.html中使用表单,且<form action="*.jsp" ...>  
    • step2,*.jsp页面的java代码中使用request.getParameter("html页面中标签的name属性的值")获取HTML页面表单标签的值

二、JSP基础语法

2.1概述

  • JSP=HTML+java代码。所以JSP页面就相当于嵌入了大量java代码的HTML页面
  • JSP语法=HTML基本语法+java语法
    • JSP中的标签都是HTML标签,和HTML标签的语法知识是一样的  
    • JSP中的java代码:核心语法来源于java,如java中的各种判断、循环语句,在JSP页面的Java代码部分都可以直接使用,但是JSP也有一些特殊的java语法
  • JSP页面中的注释,共有四种注释方法
  • JSP页面中的java代码被称作Scriptlet,JSP页面中一共有三种scriptlet
    • 常在<%!%>中  定义全局变量
    • 常在<%%>中     编写一般语句,       以及定义局部变量
    • 常用<%=%> 输出局部变量、全局变量的内容,或者直接输出一个具体的内容 
    • 备注:
      • JSP页面中尽量使用第三种scriptlet输出变量的内容,而不使用out.print()函数输出变量的内容,这样可以使得java代码和HTML代码得到分离,使得程序的可维护性得到提高
      • JSP页面中除了拥有HTML页面的所有标签之外,还有一些特殊的标签,如<jsp:scriptlet></jsp:scriptlet>标签,其使用效果和<%%>的使用效果是一样的
  • JSP页面中<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" ...其他属性及其值%>
    • 使用JSP页面的page标签可以设定该JSP页面的相关属性,具体包括设置MIME类型、导入相关包、指定错误页面、该JSP页面的编码方式等
    • 什么是MIME?答:使用MIME可以设置打开文件的应用程序类型。如JSP页面就应该设置其MIME=text/html。那么这个JSP文件被访问时,浏览器就会知道应该调用能打开*.jsp文件的应用程序来打开   该JSP文件。
    • page 标签有多个属性,不同的属性用于设置JSP页面的不同特性
    • 在同样的一个JSP页面中,page标签的所有属性中只有import指令可以多次出现,其他属性在同一个JSP页面中只能出现一次  
  • 在JSP页面中可以直接进行数据库操作
    • 编程思路:  
      • step1,在*.jsp中使用page标签的import属性将数据库操作相关的库导入到该*.jsp页面,即<%@page import="java.sql.*"%> 
      • step2,要先确保相应的数据库以及数据表已经存在,否则你就得先创建相应的数据库和数据表
      • step3,确保相应数据库的驱动程序已经正确安装(如如果使用MySQL数据库,就得先保证你已经正确安装了MySQL的驱动程序到Tomcat中),如果Tomcat没有将MySQL数据库的驱动程序加载到自己的web container中,那么运行含有操作数据库代码的*.jsp时,就会报错:找不到数据库驱动程序
      • step4,在*.jsp的java代码块中(也即scriptlet中)可以使用数据库操作相关API来操作数据库
      • step5,
    • 实例一,在JSP页面中编写数据库操作程序,向mysql数据库mlplatform的userInfo表中添加数据
    • 实例二,在JSP页面中编写数据库操作程序,读取mysql数据库mlplatform的userInfo表格中的数据,并且在JSP页面以table格式展示出来
  • 可以在JSP页面中包含其他页面(或文件)
    • 1) 源文件+被包含的files,所有的文件合在一起:<html> <head> <title> <body>这四个元素一共只能出现一次
    • 2) JSP页面包含包括静态包含和动态包含
      • 概述:通常建议使用动态包含,因为动态包含相对于静态包含有两个优点
        • 首先,动态包含可以向被包含页面传递参数,而静态包含则不可以
        • 其次,动态包含是先处理后包含,所以两个文件中定义了相同名称的变量是不会出错的。但是静态包含则不允许两个文件中定义相同名称的变量,因为静态包含指令会先将被包含页面加载进来再进行处理,如果两个文件中定义了相同名称的变量,则会报错“duplicate local variable...”  
      • 静态包含(不建议使用):
        • 被包含的文件可以是JSP文件、html文件、文本文件、java程序文件、或其他后缀名称的文件
        • 静态包含中不主动区分被包含的页面是否是静态页面,均是先将被包含的文件在JSP编译时导入,即先将被包含页面导入进来合成一个整体的文件,然后编译生成*.class文件 
        • 语法:<%@ include file="被包含的文件的路径"%> 
      • 动态包含(建议使用):
        • 被包含的文件可以是JSP文件、html文件、文本文件、java程序文件、或其他后缀名称的文件
        • 如果被包含的页面是静态文件,就先将被包含页面导入进来先合成一个整体的页面,再编译生成*.class文件;如果被包含的页面是一个动态文件,将会先执行被包含文件,然后将执行结果导入到JSP页面即可
        • 语法:
          • 不传递参数:  <jsp:include page="{被包含文件路径|<%=表达式%>}" flush=“true|false”/>  
          • 传递参数:        <jsp:include page="{被包含文件路径|<%=表达式%>}" flush=“true|false”>
                •  <jsp:param name="参数名1" value=“参数值”/> 
                •    <jsp:param name="参数名2" value=“参数值”/>
                •          ...可以    向   被包含页面  传递多个参数
                • </jsp:include>
                • 向被包含的页面传递参数,被包含的页面使用request.getParameter("参数名1")接收并使用参数
          • 关于flush属性:
            • 该属性默认值是true,表示JSP页面对应的buffer区满了之后就开始输出该JSP页面内容。
            • 若强制将该属性值设为false(通常不建议这么做),那么即使JSP页面对应的buffer满了之后也不会输出该JSP页面的内容,而是一定要等到该JSP页面的所有内容都已经加载完成之后,才开始输出该JSP页面
          • 该标签必须完结,即必须有</jsp:include>
    • 动态包含和静态包含的应用实例:
      • 参见《java web从入门到精通》 P114
  • 可以在JSP页面中通过<jsp:forward/>使得用户请求被转发到另一个页面
    • 语法:
      • 不传递参数:<jsp:forward page="目的页面路径|<%=表达式%>"/>
      • 向目的页面传递参数:
          • 可以在目的页面使用request.getParameter(“”)来获取并使用被传递给自己的参数  
            <jsp:forward page="目的页面路径|<%=表达式%>">
                <jsp:param name="" value=""/>
                可以向目的页面传递多个参数..
            </jsp:forward>
      • 该标签必须完结,即必须有</jsp:forward>

    • 使用<jsp:forward>完成的页面跳转也属于服务器端的页面跳转,浏览器地址栏中地址是不会变化的    

  • JSP页面中的九大内置对象(web container实例化的9个内置对象,可以被JSP页面scriptlet中直接调用,不用在JSP页面中new "该对象")
    • 概述:
      • jsp页面中包含java代码,所以JSP页面要在web container中才能运行
      • web container除了提供*.jsp的运行环境之外,还为运行在其中的*.jsp提供了九大内置对象来让JSP页面使用。
      • 这9大内置对象是web container实例化并且管理的,JSP页面中不用new就可以直接调用web container提供的这9大内置对象
      • (?下面的表述是否正确?)jsp中的九大内置对象是web container实例化的,所以在jsp的scriptlet中可以使用,在jsp的JavaScript中也可以使用,在jsp的javabean中也可以使用
    • web container负责实例化,可被*.jsp中scriptlet直接调用的9个内置对象:
      • 这些其实就是java EE提供的一些API,web container实际上是对这些具体的类进行了实例化,实例化之后的实例名称分别为pageContext/request/response/session/application/config/out/page/exception.在JSP的scriptlet中使用名称为request的实例就可以调用javax.servlet.http.HttpServletRequest类中的所有成员方法和公有成员变量、常量、构造函数。  
    • 编程思路:
      • step1,明确这9个内置对象对应的完整包名和类名
      • step2,明确这九个内置对象实际是web Container负责实例化的,JSP页面代码中可以直接拿这些实例化对象来用
      • step3,学习并熟记这9个内置对象对应的具体的类中的成员方法,如request对象对应的具体的类中就有如下常用方法:setAttribute()、                           getAttribute()、removeAttribute()、getParameter()   getParameterValues()   getParameterNames()   getRemoteAddr()                       setCharacterEncoding()   isUserInRole()  getSession()    getRequestURL()  getHeaderNames()  getHeader() 等方法
          • 使用request对象可以获取客户端的一些信息
          • 使用response对象可以将处理结果回应给客户端    
      • step4,了解并熟记这9个内置对象中某些对象所设置的属性的生存范围,
          • 如pageContext.setAttribute("","") 设置的属性的生存范围就只限于当前页面,在另外一个页面中是无法获取该属性的,
          • 再如request.setAttribute()设置的属性就可以保存在这一次请求中,除了定义该属性的JSP页面可以获取到该属性之外,发生服务器端页面跳转(即地址栏地址不发生改变的页面跳转)时,如错误页(404/500/503/nullPointerException)的跳转、<jsp:forword/>配置的跳转中,跳转的目的页面也可以获取request.setAttribute()中定义的属性
          • 再如session.setAttribute()设置的属性,就可以在该用户的整个会话过程中有效,无论是服务器跳转还是客户端页面跳转,目的页面都可以使用session.setAttribute()中设置的属性,只有新开浏览器,或者在换到新的浏览器之后,或者关闭此次会话之后,session.setAttribute()中设置的属性才会失效。 
          • application.setAttribute()中设置的属性对整个服务器有效,所有用户都可以使用,除非服务器关闭或重启,否则application.setAttribute()设置的属性不会失效。每个session对象都可以访问application.setAttribute()设置的属性。也即不管是不是新打开的浏览器,不管是不是使用另一台电脑访问该网站,都可以在任意JSP页面访问application.setAttribute()设置的属性。但是服务器重启之后,之前用application.setAttribute()设置的属性就会消失。最好不要设置太多application范围的属性,否则会严重影响服务器性能。
      • step5,结合step4中给出的属性的有效范围,还需要理解并牢记各种跳转的区别:
          • 如网站的错误跳转(404,500,503,NullPointerException跳转等),就是服务器端跳转,浏览器地址栏不改变
          • 再如JSP标签<jsp:forward/>也是服务器端跳转,浏览器地址栏不改变
          • 而<a href=""/> 之类的跳转就是客户端跳转,浏览器四芝兰改变
          • 新打开一个浏览器时,服务器会为每个新打开的浏览器分配一个新的session对象,不同session对象之间不可以互相传递属性,(如新打开的浏览器的*.jsp页面中不可以访问已经打开了一段时间的浏览器的*.jsp中session.setAttribute()设置的属性) 
          • response.setRedirect()是客户端跳转,浏览器地址栏改变
          • response.setHeader(refresh,(3,URL))跳转也是客户端跳转,浏览器地址栏改变  
  • 在jsp页面中使用javabean
    • 在jsp页面中使用javabean的好处:
        • 首先,可以使得java代码从*.jsp中分离出来,增加代码重用性以及可维护性
        • 其次<jsp:javaBean/>以及<jsp:setProperty />这两个标签的使用,可以简化*.jsp页面代码
            • 使用<jsp:javaBean/>标签的话就可以省略scriptlet中使用自定义javabean类创建一个对象实例的相关代码
            • 使用<jsp:setProperty name="javabean实例名" property=“*”/>标签的话就可以省略scriptlet中将form表单元素值赋值给javabean对象的属性的相关代码
                • 1.因为“*”表示表单标签和javabean实例的相应属性会按照名称去匹配,表单标签的值会被自动赋值给javabean实例中相同名称的属性,所以javabean中相应属性应该有对应的setter函数 
                • 2.String类型的表单标签的值还会自动变成javabean中相应属性的类型,如string类型的表单标签值自动变成int型来赋值给javabean中的age:int属性。由于javabean中age:int属性是int型的,所以表单标签<input type="" name="age">中输入的值必须是一个有效数值,否则会抛出NumberFormatException异常,所以表单在提交之前,最好在javascript中进行验证 
                • <jsp:setProperty/>还有其他三种用法:  
    • 如何在jsp中使用javabean(编程思路):
        • step1,编写javabean,即*.java
              • 该类必须是public class
              • 该类中属性必须是private的,若外部需要使用相应属性,就必须有相应getter或setter函数
              • 该类必须至少含有一个无参构造函数
        • step2,在jsp页面中引用该javabean
          • (不常用)方法一,使用<%@page import="包名.javabean类名"%>
          • (常用)方法二,使用<jsp:useBean id="" scope="" class=""/>
              • 其中scope属性一共有四种可能的取值,分别为page、request、session、application
              • 如<jsp:useBean id="" scope="page" class=""/>
              • 其实使用该标签引入一个javabean实例就相当于添加了一个相应范围的属性(即添加了一个javabean实例对象作为page/request/session/application范围的属性) 
              • 由于新声明的javabean实例对象就是相当于添加了一个相应范围的属性,所以可以使用九大内置对象删除相应范围内的javabean对象
                  • pageContext.removeAttribute("javabean实例名")
                  • request.removeAttribute("javabean实例名") 
                  • session.removeAttribute("javabean实例名")  
                  • application.removeAttribute("javabean实例名")   
        • step3,了解<jsp:setProperty/>标签的用法:
          • 当将表单标签值赋值给javabean相应属性时,会自动实现类型转换,如String 类型的表单标签值转成int型后再赋值给javabean的age:int属性,所以表单输入页面一定要保证输入的值是一个有效的数值,否则会抛出NumberFormatException异常(为了避免出现这种异常,可以在表单输入页面使用JavaScript对输入的内容进行格式验证)

        •  

          step4,了解<jsp:getProperty/>标签的用法:
          • 该标签只有一种语法格式<jsp:getProperty name="javaBean实例名称" property=“javaBean实例的属性名称”/>
          • 该标签会自动调用javabean实例的相应getter方法
          • 该标签   等价于    <%= javabean实例名.getXxx() %>    
    • javabean的分类:
        • 类型一,简单javabean(POJO/vo/TO),这样的javabean只有属性及其对应的setter、getter函数,没有其他构造函数和成员函数
    • 在jsp页面中使用javabean的实例:
        • 实例一,用<jsp:useBean/>包含自定义的javabean对象,并且为该javabean对象的属性赋值,并且获取该javabean对象的属性 的值并在jsp页面中展示
            • 代码,见    《java web开发实战经典.pdf  P188》
        • 实例二,用<jsp:useBean/>以及<jsp:setProperty/> 
            • 代码,见    《java web开发实战经典.pdf  P191》   

2.2基础语法知识(2.1节各条知识点详解)

  • JSP页面中的注释,共有四种注释方法:
    • 显式注释,注释内容会被发送到客户端(浏览器)
    • 隐式注释,注释内容不会被发送到客户端(浏览器)

    • 浏览器中在*.jsp页面---->鼠标右键--->查看源代码。可以看到该JSP页面的包含在<!-- -->中的注释内容,其他类型的注释内容是看不到的,因为服务器根本就没有将这些类型的注释(隐式注释内容)发送到客户端浏览器
  • JSP页面中的scriptlet,一共有三种scriptlet(scriptlet中是java代码)
    • 第一种,<%!%>
      • 这种scriptlet中只能定义全局变量、全局方法、全局类
      • 尽量不要在JSP中使用<%!%>定义全局方法、全局类,尽管JSP支持这样的定义,当JSP中需要使用方法或者类的时候,通常使用Javabean而不是在<%!%>中定义
      • 这里面不能使用其他语句,如out.print()语句就不可以直接写在这里面,所以一般结合<%%>  使用
    • 第二种,<%%>
      • 这里面可以定义局部变量
      • 还可以编写语句,如out.println()  
    • 第三种,<%=%>  
    • 实例一,
      • <%@ page language="java" contentType="text/html; charset=UTF-8"
            pageEncoding="UTF-8"%>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        <html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP基础语法知识</title>
        </head>
        <body>
            <!-- JSP页面的scriptlet,共有三种 -->
            <%!
                /*这种Scriptlet中可以定义全局变量、全局方法、全局类
                    不过一般只使用它定义全局变量
                    JSP中如果要使用方法和类,最好是在JavaBean中定义
                */
                public static final String INFO="JSP页面的scriptlet中定义的一个全局常量"; //全局变量
            %>
            <% 
                /*这种scriptlet中可以定义局部变量,可以编写一般的语句
                */
                int x=10;//局部变量
                String name="JSP页面的scriptlet中定义的一个局部变量";
                out.println("<h1>访问局部变量:</h1>\nx="+x);
                out.println("<h1>访问全局变量:</h1>\nstr="+INFO);
            %>
            <center>
                局部变量:<%=name %><br>
                全局变量:<%=INFO %><br>
                JSP页面的scriptlet中直接输出一个特定内容:<%="特定内容" %>
            </center>
            
        </body>
        </html>
  • JSP页面的<%@page 属性=“值"...%>

    • page标签的可用属性有:

        • 备注:
          • 关于contentType属性
            • contentType=“text/html;charset=GBK” 则该页面以HTML文本文件进行显示,且页面编码方式是GBK
            • contentType=“test/html;charset=GBK”    则访问该页面时,浏览器会出现一个下载提示框,让你下载*.jsp(即该JSP页面) 
            • contentType=“application/msword;charset=GBK” 则访问该页面的时候,浏览器会调用word程序,你可以选择将该页面保存成*.doc文档,也可以选择直接使用word程序打开该页面
            • contentType也可以设置成其他的值,使得通过浏览器访问该*.jsp页面时,浏览器可以调用其他的编辑器打开该JSP页面,或者将该JSP页面保存成其他类型的文档,如*.doc、*.jpg
            • contentType都可以取哪些值,详情参见Tomcat安装目录/conf/web.xml中<mime-mapping>标签中内容
    • 使用实例:

      • 实例一,设置JSP页面的MIME属性,可以设置为将该JSP页面保存成*.doc、*.jpg等 

      • 实例二,可以通过JSP页面的page标签设置*.jsp页面的编码方式:通过<%@page pageEncoding=""%>指定

      • 实例三,可以设置服务器发送给客户端的内容的编码方式,通过page标签的contentType的charset指定

      • 实例四,可以通过errorPage属性和isErrorPage属性指定错误页,这样一来访问*.jsp时,如果该JSP页面出现了错误,就会跳转到该JSP页面的<%@page isErrorPage=""%>指定的错误页,但是要相应的错误页的page标签的isErrorPage属性的值为true才可以

        • 会自动跳转到指定的错误页  
        • 该跳转是服务器端跳转(浏览器地址栏地址没有改变)
        • 整个操作过程中,客户端只向服务器发送了一次请求,服务器也只向客户端响应了一次

 

  • 在JSP页面中可以直接进行数据库操作
    • 编程思路:  
      • step1,在*.jsp中使用page标签的import属性将数据库操作相关的库导入到该*.jsp页面,即<%@page import="java.sql.*"%> 
      • step2,要确保待操作的数据库以及数据表格是存在的
        • 假定要操作的数据库是MySQL数据库
        • 假设在MySQL中已经建立了一个数据库mlplatform
        • 且该数据库中有一张数据表格userInfo,且该表格的内容如下:
          USE mlplatform;
          DROP TABLE IF EXISTS userInfo;
          CREATE TABLE userInfo(
              userId INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
              userName VARCHAR(10),
              password VARCHAR(20),
              registerDate DATE,
              email VARCHAR(40)
          );
          INSERT INTO userInfo(userId,userName,password,registerDate,email)
              VALUES(0001,'administrator','0','2017-04-14','123@163.com');

        • 在上述这些条件下学习如何在*.jsp中直接操作数据库。
      • step3,先确保已经正确安装了相应数据库的驱动程序
        • 由于使用MySQL数据库,所以首先要配置MySQL数据库驱动程序,具体操作步骤如下:
          • 将MySQL的驱动程序复制到Tomcat/lib目录下 
          • 重启服务器(tomcat),使得新配置的jar包被加载到web container容器中(如果不重启,新配置的jar包没有加载进来,那么程序运行时可能会抛出找不到驱动程序的错误) 
      • step4,开始在*.jsp中编写数据库操作代码 
        • <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
          <%@ page import="java.sql.*" %> <%@ page import="java.util.Date" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>在JSP中直接操作数据库</title> </head>

          <body>
          <%--下面在JSP页面中直接添加数据库操作程序,将用户注册信息添加到数据库mlplatform的userInfo表格中 --%> <%! //定义数据库驱动程序(这个驱动程序就是step3中添加到Tomcat安装目录/lib/目录下的mysql数据库驱动程序) public static final String DBDRIVER="com.mysql.jdbc.Driver"; //数据库连接地址,mysql默认端口是3306,mlplatform是在mysql中创建的数据库 public static final String DBURL="jdbc:mysql://localhost:3306/mlplatform"; //数据库连接用户名和密码(连接mysql数据库的用户名和密码) public static final String DBUSER="root"; public static final String DBPASS="yourMysqlPassword"; %> <% Connection conn=null; PreparedStatement pstmt=null; try{ Class.forName(DBDRIVER); conn=DriverManager.getConnection(DBURL,DBUSER,DBPASS); //向数据库的userInfo表格中添加一条记录String sql="INSERT INTO userInfo(userName,password,registerDate,email)VALUES('test','0','2017-04-14','123@163.com')"; pstmt=conn.prepareStatement(sql); pstmt.execute(sql); }catch(Exception e){ e.printStackTrace(); }finally{ //rs.close(); pstmt.close(); conn.close(); } %> </body> </html>
            
      • step5,测试你的程序能否正确运行
        • 在浏览器中访问step4中创建的*.jsp页面
        • 然后查看你的mysql数据库中相应表格中是否增加了新的数据记录(DOS命令行操作数据表)   
    • 实例一,在JSP页面中编写数据库操作程序,向mysql数据库mlplatform的userInfo表中添加数据
      • 具体代码参见上述“编程思路”部分,那里给出的程序就是实现了这个功能    
    • 实例二,在JSP页面中编写数据库操作程序,读取mysql数据库mlplatform的userInfo表格中的数据,并且在JSP页面以table格式展示出来
      • 代码如下: 
  • JSP页面中的九大内置对象(web container实例化的9个内置对象,可以被JSP页面scriptlet中直接调用,不用在JSP页面中new "该对象")
    • request内置对象对应于javax.servlet.http.HttpServletRequest类,该类中较为常用的成员方法有:
        •  
        • 学会区分“*.jsp页面本身的编码方式” “响应的编码方式(即服务器端传递给客户端的数据的编码方式)”   “请求参数的编码方式(即客户端传递给服务器的请求参数的编码方式)” 
            • 浏览器默认编码方式是UTF-8,所以用户传递给服务器的请求参数都是以utf-8这种编码方式来编码的,如果服务器端使用的编码方式不是utf-8,就有可能出现乱码,为了解决乱码,可以使用request.setCharacterEncoding("")先以服务器端可以理解的编码方式将服务器端接收到的请求参数“翻译”一下,再交给后面的处理程序使用。
            • JSP页面中<%@page pageEncoding=""%>设置的是*.jsp页面的页面编码
            • JSP页面中<%@page contentType="text/html,charset="" "%>设置的是服务器向客户端传送的数据的编码方式
        • 接收到的数据的编码方式和本地编码方式不一致时,就会出现乱码
        • 使用web container提供的request对象(也即javax.servlet.http.HTTPServletRequest类对象),可以接收客户端传递给服务器的参数
            • request.getParameter()可以接收只有一个值的请求参数
              • 如text、radio、password、hidden之类的只有一个值的表单控件
              • 再如通过地址重写方式传递的参数:动态页面地址?param1=value1&param2=value2&param3=value3...
            • request.getParameterValues()可以接收拥有多个值的请求参数
              • 如复选框checkbox之类的表单控件,可能有多个值,必须用request.getParameterValues()接收
              • 再如通过地址重写方式传递的参数:动态页面地址?param1=value1&param2=value2&param3=value3...
            • request.getParameterNames()可以接收所有请求参数的名字集合
              • 只要请求页面*.jsp中表单元素遵循特殊的命名规范  
              • 上述函数  结合Enumeration类中的成员方法  
              • 就可以实现*.jsp的模板式解析
              • 实例:参见《java web开发实战经典.pdf P142》
            • 上述函数用于接收表单参数的时候,可能表单控件中根本就没有输入内容,这时使用上述函数得到的参数的值就为null,后续程序如果用到这些null值,就有可能抛出NullPointerException,所以接收了请求参数的值之后,对这些值进行后续处理之前,最好先判断是否为空  
        • 表单提交的get和post有什么不同?
            • get方式提交,请求参数都会显示在浏览器地址栏
            • post方式提交请求,请求参数不会显示在浏览器地址栏
            • 所以get方式提交时,请求参数的大小受限(4-5KB)
            • 所以当请求参数中包含大文本或者图片时,只能用post方式提交请求    
        • 在服务器端可以使用request对象获取客户端的头信息 
            • 头信息包括主机IP、使用的语言、cookie、CPU位数等等
            • 头信息的存在使得服务器端能够了解客户端机器的相关信息
            • request.getHeaderNames()
            • request.getHeader()  
        • request对象可以用于角色验证,配合实现权限控制
            • 《java web开发实战经典.pdf  P144》 
        • 使用request对象还可以获取客户端IP、本JSP页面的地址URL、上下文路径     
        • 总而言之一句话:在服务器端的*.jsp中使用request对象可以获得客户端的一些信息

                
    • response内置对象(对应于javax.servlet.http.HTTPServletResponse)
        • 常用成员方法
        • 通过response对象可以设置客户端的头信息

            • 如设置定时刷新response.setHeader("refesh","2") 设置成每隔两秒刷新一次客户端所显示的该页面(*.jsp) 

            • 如设置3秒后自动跳转到另一个页面response.setHeader("refresh","3;URL=hello.jsp") 

        • 通过response对象可以实现客户端页面跳转

            • 方法一,response.setHeader("refresh","time:URL")  客户端页面跳转(地址栏URL改变)

            • 方法二,response.sendRedirect("") 客户端页面跳转(地址栏URL改变) 

        • 通过response对象可以添加cookie到客户端(保存一些信息在客户端,提高程序运行效率,缩短响应延迟)

            • 关于Cookie:参见博客

            • 编程思路:(如何使用cookie技术)

              • step1,了解一些基础知识(即操作Cookie的一些类和成员方法)

              • step2,创建Cookie对象

              • step3,使用response.addCookie(Cookie cookie)将step2中新建的cookie对象添加到客户端浏览器  

              • step4,step2-step3通过response对象设置到客户端的cookie可以被客户端机器获取并作后续处理,这些cookie信息被保存在客户端机器中(生存时间由相应设置来决定),不用服务器端重复传送,客户端机器可以随时取用,

              • step5,由于客户端每次向服务器端发送请求时,都会将本地机器中保存的cookie信息放在header头信息中一起发送到服务器端,所以服务器端也可以获得保存在客户端机器中的cookie对象的值,并根据客户端机器中的Cookie的值作出后续操作

            • 实际编程实例:参见博客“MLPlatform开发日志step12
            • 上述程序的运行原理:客户端通过浏览器访问login.jsp时,会将客户端机器上保存的cookie信息一起发送到服务器上,服务器在组装login.jsp的时候,会先获取Cookie中的信息,并且将cookie中的信息值作为login.jsp相应表单标签的默认值

    • session对象(可以用于完成用户登录的合法性验证)    

        • 常用成员方法:session实际是javax.servlet.http.HttpSession接口实例化的对象
          • setAttribute()、getAttribute()、removeAttribute()...  
        • session.getId()的返回值实际上和Cookie中的JSESSIONID的值是一样的,都=服务器为了唯一标识每个客户端而为每个连接到该服务器的客户端自动分配的唯一标识符。

            • session.getId()=Cookie:JSESSIONID=服务器端自动分配的客户端唯一标识符

            • 使用session.getId()可以获取该唯一标识符

            • 使用request.getCookies()也可以获取该唯一标识符

            • 服务器重启之后,之前为每一个客户端分配的唯一标识符也都失效,服务器重启之后,会再次为客户端分配新的客户端唯一标识符,但是也可以通过一定的设置,使得服务器重启后之前分配的客户端唯一标识符不失效,只需在服务器重启前将已经分配的客户端唯一标识符给序列化保存到一个临时文件中,服务器重启后再根据该临时文件将保存的所有客户端唯一标识符反序列化,就可以实现上述功能。具体操作方式参见:《java web开发实战经典.pdf  P158》 

        • 可以将登录成功的用户的用户名保存成session范围的属性,之后可以根据session中有没有该用户的用户名来判断该用户是否已经登录,然后就可以用于权限控制

            • step1,用户登录

            • step2,登录成功的用户的用户名被保存成session范围的属性session.setAttribute("username",username)

            • step3,该用户想要访问某个只有登陆的用户才可以访问的资源时,就可以用session.getAttribute("username")来获取,如果结果为空,就说明该用户未登录,跳转到登录页面让用户登录,如果结果不为空,则说明该用户已经登录,则跳转到相应的资源

        • session.invalidate()实现注销功能  

        • session.isNew()根据有没有JSESSIONID判断该用户是否是新用户,刚连接上服务器时还没来得及获取服务器自动分配的JSESSIONID,所以没有JSSEIONID的session被判作“新用户”。

        • session.getCreationTime()获取该session创建的时间

        • session.getLastAccessedTime()获取该session最后一次操作的时间 

    • application对象(用于操作整个web container的相关属性) 

        • application对应于javax.servlet.ServletContext

        •  使用application.getRealPath()获取虚拟目录对应的真实目录

            • 实例一,String realPath=application.getRealPath("/");//获取当前虚拟目录下对应的真实路径

            • 实例二,String realPath=this.getServletContext().getRealPath("/");      这个和上面的例子等价(因为application可以通过this.getServletContext()获得,其中this指代它所在的*.jsp)
            • 实例三,在网页input.html中输入文档标题和文档内容,将其存成*.txt文件,保存在工程文件夹下的/file/txt/文件夹下:
                • 具体实现参见《java web 开发实战经典.pdf    P165》  
            • 实例四,可以使用操作一个文件count.txt的方式记录我们的网站的访客数
                • 具体实现参见《java web 开发实战经典.pdf    P167-----“网站计数器”》
        • application.getAttributeNames()获取所有application范围的属性

            • 上述代码等价于this.getServletContext().getAttributeNames()

    • config对象(用于获取web.xml中配置的初始化参数)

        • 一个网站必须有WEB-INF文件夹
        • WEB-INF文件夹安全级别较高,一般在WEB-INF文件夹下放一些配置文件
        • 存放在WEB-INF文件夹下的*.jsp   *.html等页面不能直接被访问到,要想访问WEB-INF文件夹下的相应页面,必须在web.xml中进行一定的配置才行(具体配置方法参见《java web开发实战经典.pdf      P171  》)    
        • web.xml修改后要重启服务器,新的配置才能生效  
        • 在web.xml中使用<init-param>定义的参数,需要使用jsp九大内置对象中的config来获取并进行后续使用
        • config对象是javax.servlet.ServletConfig类实例化后的对象,该类中常用成员方法有
        • 可以在web.xml中定义一些生存与整个project的变量,如DBDriver、DBURL、DBusername、DBpassword等等,然后在JSP中使用其九大内置对象中的config来获取并使用web.xml中定义的这些变量。

    • out对象

        • out对象对应于javax.servlet.jsp.JspWriter 类
        • 该类中的常用成员方法有:
            • out.print()向jsp页面输出内容
            • out.println()
            • out.getBufferSize()获取jsp页面对应的缓冲区大小
            • out.getRemaining()   
    • pagecontext对象

        • pageContext对应于javax.servlet.jsp.PageContext类       

        • 该类表示一个jsp页面上下文

        • 该类中常用成员方法:

            • 操作页面范围属性,pageContext.setAttribute()/getAttribute()/removeAttribute()
            • 定义request、response、application范围属性:pageContext.setAttribute(String name,Object value,int scope)
                • 如pageContext.setAttribute("name","lxrm",PageContext.REUQEST_SCOPE)
                • pageContext.setAttribute("birthday",new Date(),APPLICATION_SCOPE)  
            • 其他成员函数:
              • 用于页面跳转pageContext.forward()====》<jsp:forward/>
              • 用于页面包含pageContext.include()=====》<jsp:include/>
              • 用于获取ServletContext/ServletConfig/ServletRequest/ServletResponse/HttpSession对象

  

 

 

posted on 2017-04-12 11:38  LXRM-JavaWeb、ML  阅读(306)  评论(0编辑  收藏  举报

导航