Java Web学习笔记

1.常见的状态码:
    404:资源不存在;
    200:一切正常;(一般看不见)
    403:权限不足;
    300/301:页面重定向(跳转);
    500:服务器内部错误;(代码有误)
    其他编码:需要积累;

2.jsp:在html中嵌套的java代码;

3.在项目/WEB-INF/web.xml中设置 默认的 初始页面:
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

4.虚拟路径:
    方式一:
    将web项目配置到webapps以外的目录
    conf/server.xml中配置
    host标签中:
    docBase:实际路径;
    path:虚拟路径;(绝对路径、相对路径)
    需要重启;
    方式二:
    tomcat\conf\Catalina\localhost中新建“项目名.xml”中新增一行:
        <Context   docBase="F:\tomcat\webapps\helloworld"   path="/helloworld"  />

5.虚拟主机:(不常用)
    通过www.test.com访问本机;
    配置conf/server.xml文件
<Engine  name="Catalina"  defaultHost="www.test.com">
    <Host  appBase="F:\tomcat\webapps\helloworld"  name="www.test.com">
        <Context  docBase="F:\tomcat\webapps\helloworld"  name="/"/>
    </Host>
</Engine>
    在C:\Windows\System32\drivers\etc\host中
    增加
    127.0.0.1        www.test.com
    流程:www.test.com->host找映射关系->server.xml找Enginede defaultHost->通过“/”映射到F:\tomcat\webapps\helloworld

6.客户端访问服务端,JSP执行流程:
    第一次访问:服务端jsp翻译成java(Servlet文件),java编译成class文件;
    第二次访问:直接访问class文件;(如果服务端代码修改了,将会在访问时重新翻译、编译)
    jsp和servlet可以相互转换;
    因为第一次请求服务端会有翻译和编译的过程,因此比较慢,后续访问可以直接访问class,因此比较快,但是如果服务端修改了代码,则再次访问时会重新的翻译和编译;

7.在Eclipse中创建的Web项目:
    浏览器可以直接访问WebContent中的文件,但是WEB-INF中的文件,无法通过客户端(浏览器)直接访问,只能通过请求转发来访问;
    注意:并不是任何的内部跳转都能访问WEB-INF;原因是跳转有2种方式:请求转发、重定向;
    部署tomcat,在server是面板新建一个tomcat实例,再在该实例中部署项目(右键-add)
    注意:一般建议将eclipse中的tomcat与本地的配置信息保持一致:将eclipse中的tomcat设置为托管模式:【第一次】创建tomcat实例之后,双击该实例,选择Server Location的第二项;

8.统一字符集编码
    a.编码分类:
        设置jsp文件的编码(jsp文件中的怕个Encoding属性):jsp->java;
        设置浏览器读取jsp文件的编码(jsp文件中content属性);
        一般需要将上述设置成一致的编码,推荐使用UTF-8;
文本编码:
    将整个eclipse文件中的文件统一设置;(推荐)
    设置某一个项目
    设置单独文件

9.JSP的页面元素:
    脚本Scriptlet
        <%
            局部变量、java语句(需要分号)
        %>

        <%!
            全局变量、定义方法
        %>

        <%=
            输出表达式(无需分号)
        %>
    一般而言,修改web.xml、配置文件、java需要重新启动tomcat服务,但是如果修改了Jsp/html/css/js,不需要重启;
    注意:out.println()不能回车;要想回车:“<b/>”(相当于方法的输出结果在HTML文件中,HTML文件中有回车,但是在网页中并不会回车)

10.JSP的页面指令:
    page指令
    <%@ page...%>
    page指令的属性:
        language:jsp页面使用的脚本语言(java代码);import:导入类;pageEncoding:jsp文件自身编码;contentType:浏览器解析jsp的编码;

11.jsp页面元素注释:
    html注释:<!-- -->(在页面通过浏览器查看源码可以观察到)
    java注释://  /*... */
    jsp注释:<%--  --%>

12.JSP九大内置对象(自带的,不需要new也能使用的对象)
    out:输出对象,向客户端输出内容;

    request:请求对象;存储“客户端向服务端发送的请求信息”;
        request对象常见方法:
            String getParameter(String name):根据请求的字段名key(input标签的name属性),返回字段值value(input标签的value属性值);
            String[] getParameterValues(String name):根据请求的字段值key,返回多个字段值value(常见的checkbox:多选按钮);
            setCharacterEnoding(“编码格式utf-8”):设置post方式的请求编码;(默认编码:tomcat7及以前默认iso-8859-1,tomcat8以后改为了utf-8)
            getRequestDispatcher().forward(request,response):请求转发的方式跳转页面;
        ServerContext getServerContext():获取项目的ServletContext对象;
    示例:注册
        register.jsp(注册页),show.jsp(展示页)
    http://localhost:8888/MyJspProject/show.jsp?uname=zs&upwd=123&uage=23&uhobbies=%E8%B6%B3%E7%90%83&uhobbies=%E7%AF%AE%E7%90%83&uhobbies=%E4%B9%92%E4%B9%93%E7%90%83
连接/文件?参数名1=参数值1 & 参数名2=参数值2 & 参数名3=参数值3;
        get提交方式:method="get" 和 地址栏  、超链接(<a href=“xx”>) 请求方式 都默认属于get提交方式
        get与post请求方式的区别:
        a.    get方式 在地址栏显示 请求信息(但是地址栏能够容纳的 信息有限,4-5KB;如果请求数据存在大文件,图片等 会出现地址栏无法容纳全部的数据而出错);post不会显示;
        b.    文件上传操作,必须是post;
        推荐使用post;
    统一请求的编码 request
        get方式请求 如果出现罗马,解决:
        a.统一每一个变量的 编码 (不推荐)
            new String(旧编码,新编码);
        b.修改server.xml,一次性的 更改tomcat默认get提交方式的编码(utf-8)
        建议 使用tomcat, 首先在server.xml中 统一get方式的编码.. URIEnocding="UTF-8"

    response:响应对象
        提供的方法:
            void addCookie(Cookie cookie);服务端向客户端增加cookie对象
            void sendRedirect(String location) throws IOException;页面跳转的一种方式(重定向)
            void setContentType(String type);设置服务端相应的编码(设置服务端的contentType类型)
        示例:登录
            login.jsp->check.jsp ->success.jsp
            请求转发        重定向
地址栏是否改变        不变(check.jsp)    改变(success.jsp)
是否保留第一次请求时的数据    保留        不保留
请求的次数        1        2
跳转发生的位置        服务端        客户端发出的第二次跳转    
    
    session:会话(服务端)session存储在服务端、session是在同一个用户(客户)请求时共享;
        a.浏览网站:开始-关闭
        b.购物:浏览、付款、退出
        c.电子邮件:浏览、写邮件、退出
    session机制:
            客户端第一次请求服务端时,服务端会产生一个session对象(用于保存该客户的信息)并复制;并且每个session对象 都会有一个唯一的sessionId(用于区分其他session);服务端又会 产生一个cookie,并且 该cookie的name=JSESSIONID,value=服务端sessionId的值;然后 服务端会在 响应客户端的同时 将该cookie发送给客户端,至此 客户端就有 一个cookie(JSESSIONID);因此 客户端的cookie就可以和服务端的session一一对应(JSESSION-sessionID)
            客户端第二次/n次请求服务端时:服务端会先用客户端cookie中的JSESSIONID 去服务端的session中匹配sessionId,如果匹配成功(cookie JSESSIONID和session sessionId),说明此用户 不是第一次访问,无需登录;
        例子:
            客户端:        -顾客 (客户端)
            服务端:存包处    -商场(服务端)
            顾客第一次存包:商场 判断此人是否 之前已经存过包(通过你手里是否有钥匙);如果是新顾客(没钥匙),分配一个钥匙 给该客户;钥匙 会和 柜子 一一对应;
            第二次/n次 存包:商场 判断此人是 之前已经存过包(通过你手里是否有钥匙);如果是老顾客(有钥匙),则不需要分配;该顾客手里的钥匙 会和 柜子 自动一一对应;
        session方法:
            String getId():获取sessionId;
            boolean isNew():判断是否  新用户(第一次访问)
            void invalidate():使session失效(退出登录、注销)
            void setAttribute()
             Object getAttribute()
            void setMaxInacttiveInterval(秒):设置最大有效 非活动时间
            int getMaxInactiveIinterval():获取最大有效 非活动时间
        cookie和session的区别:
        session        cookie
保存位置        服务端        客户端
安全性        较安全        较不安全
保存的内容    Object        String
    
        Cookie(客户端,不是内置对象):Cookie是由 服务端生成的,在发送给客户端保存;相当于 本地缓存的作用:客户端(hello.mp4,zs/abc)->服务端(hello.mp4,zs/abc);作用提高访问服务端的效率,但是安全性较差;
        客户端在第一次请求服务端时,如果服务端发现 此请求没有JSESSIONID,则会创建一个 name=JSESSIONID的cookie;
        cookie:
            a.不是内置对象,要使用必须new
            b.但是,服务端会 自动生成一个(服务端自动new一个cookie) name=JSESSIONID的cookie 并返回给客户端;        
        Cookie:name=value;
        javax.servlet.http.Cookie
        public Cookie(String name,String value):产生Cookie
        String getName():获取name
        String getValue():获取value
        void setMaxAge(int expiry):最大有效期(秒)
        服务端准备Cookie:
        response.addCookie(Cookie cookie)
        页面跳转(转发,重定向)
        客户端获取Cookie:request.getCookies();
        a.服务端增加cookie:response对象;客户端获取cookie:request对象;
        b.不能直接获取某一个单独对象,只能一次性将 全部的cookie拿到;
        通过F12可以发现 除了自己设置的Cookie对象外,还有一个name为JSESSIONID的cookie
        建议cookie只保存 英文数字,否则需要进行编码、解码
        使用Cookie实现 记住用户名 功能        
    
    application:全局对象 获取路径
        String getContextPath();虚拟路径
        String getRealPath(“虚拟路径”);绝对路径;

    pageContext:JSP页面容器
    config:配置对象(服务器配置信息)
    page:当前JSP页面对象(相当于java中的this)
    exception:异常对象
    out:输出对象

    四种范围对象(小->大)
        pageContext:JSP页面容器(page对象);当前页面有效(页面跳转后无效);
        request:请求对象;同一次请求有效(请求转发后有效;重定向后无效);
        session:会话对象;同一次会话有效(无论怎么跳转,都有效;关闭/切换浏览器后无效;从 登录->退出 之间 全部有效);
        appliation:全局对象;全局有效(整个项目运行期间都有效;切换浏览器仍有效);关闭服务、其他项目 无效;如果想多个项目共享、重启后仍然有效:可通过JNDI技术;
    1.以上4个范围对象,通过setAttribute()赋值,通过setAttribute()取值;
    2.以上范围对象,尽量使用最小的范围;因为 对象的范围越大,造成的性能损耗越大;
    以上4个对象共有的方法:
        Object getAttribute(String name):根据属性名,获取属性值
        void setAttribute(String name,Object obj):设置属性值(新增,修改),如果不存在则创建,如果存在则修改;
        void removeAttribute(String name):根据属性名,删除对象

13.JDBC:
    Java DataBase Connectivity 可以为多种关系型数据库DBMS 提供统一的访问

    JDBC API 主要功能:

        三件事,具体是通过以下类/接口实现:

            DriverManager:管理JDBC驱动

            Connection:连接(通过DriverManager产生)
                Connection产生操作数据库的对象:Statement对象:createStatement();PreparedStatement对象:prepareStatement(sql);CallableStatement对象:prepareCall();
            Statement(PreparedStatement):增删改查(通过Connection产生)
                Statement操作数据库:增删改:executeUpdate();查询:executeQuery();
                PreparedStatement操作数据库:增删改:executeUpdate();查询:executeQuery();赋值操作:setXxx();
                PrepareStatement(继承自Statement)与Statement在使用时的区别:
                    1.Statement:sql;executeUpdate(sql);
                    2.PreparedStatement:sql(可能存在占位符:?);在创建PrepareStatement对象时,将sql预编译prepareStatement(sql);executeUpdate();setXxx()替换占位符?;
                推荐使用PreparedStatement:原因如下:
                    1.编码更加简便(避免了字符串的拼接)
                        String name=“zs”;int age=23;
                        stmt:
                        String sql=“insert into student(stuno,stuname) values(‘“+name+”’,“+age+”)”;
                        stmt.executeUpdate(sql);
                        pstmt:
                        String sql=“insert into student(stuno,stuname) values(?,?)”;
                        pstmt=connection.prepareStatement(sql);//预编译SQL
                        pstmt.setString(1,name);
                        pstmt.setInt(2,age);
                    2.提高性能(因为 有预编译操作,预编译只需要执行一次)
                        需要重复增加100条(批量处理)
                        String name=“zs”;int age=23;
                        stmt:
                        String sql=“insert into student(stuno,stuname) values(‘“+name+”’,“+age+”)”;
                        stmt.executeUpdate(sql);
                        pstmt:()
                        String sql=“insert into student(stuno,stuname) values(?,?)”;
                        pstmt=connection.prepareStatement(sql);//预编译SQL
                        pstmt.setString(1,name);
                        pstmt.setInt(2,age);
                    3.安全(可以有效防止sql注入)(sql注入:将客户输入的内容 和 开发人员的SQL语句 混为一体)
                        stmt:存在被sql注入的风险(例如输入 :用户名:任意值 ‘ or 1=1 --; 密码:任意值;)

            CallableStatement:调用数据库中的 存储过程/存储函数(通过Connection产生)(connection.prepareCall(参数:存储过程或存储函数名);参数格式:存储过程(无返回值return,用Out参数替代):{call 存储过程名(参数列表)};存储函数(有返回值return):{?=call 存储函数名(参数列表)})
            JDBC调用存储过程的步骤:
                a.产生 调用存储过程的对象(CallableStatement) cstmt=connection.prepareCall(“...”);
                b.通过setXxx()处理 输出参数值 cstmt.setInt(1,30);
                c.通过registerOutParameter(...)处理输出参数类型
                d.cstmt.execute()执行
                e.接收 输出值(返回值)getXxx()
            JDBC调用存储函数:与调存储过程的区别:
                在调用时,注意参数:“{?=call addTwoNumfunction (?,?)}”
                
                ResultSet:返回的结果集(next():1.下移;2.判断下移之后的元素是否有数据,如果有数据:true,如果无数据:false)(previous():向上,同next();getXxx(字段名/位置):获取具体的字段值)(上面的Statement等产生)

    JDBC访问数据库的具体步骤:
        a.导入驱动(导入jar包),加载具体的驱动类(Class.forName(“oracle.jdbc.OracleDriver”);)
        b.与数据库建立连接(Connection connection=DriverManager.getConnection(URL,UNAME,UPWD);)
        c.发送SQL,执行(增删改、查)(增删改:Statement stmt=connection.createStatement();int cout=stmt.executeUpdate(sql);)(查:Statement stmt=connection.createStatement();)
        d.处理结果集(查询)(ResultSet rs=stmt.executeQuery(sql);while(rs.next()){rs.getInt(“字段名1”);rs.getString(“字段名2”);})

    JDBC中,除了Class.forName() 抛出ClassNotFoundException,其余方法全部抛SQLException;

    数据库驱动
                驱动jar                具体驱动类                连接字符串(数据库名、ip地址、端口号、名字)        
        Oracle        ojdbc-x.jar            oracle.jdbc.OracleDriver            jdbc:oracle:thin:@localhost:1521:ORCL
        MySQL        mysql-connector-java-x.jar        com.mysql.jdbc.Driver            jdbc:mysql://localhost:3306/数据库实例名
        SqlServer        sqljdbc-x.jar            com.microsoft.sqlserver.jdbc.SQLServerDriver    jdbc:microsoft:sqlserver:localhost:1433;databasename=数据库实例名
    使用jdbc操作数据库时,如果对数据库进行了更换,只需要替换:驱动、具体驱动类、连接字符串、用户名、密码;    
    
    处理CLOB/BLOB类型
        处理稍大型数据:
            a.存储路径(通过JDBC存储文件路径,然后 根据IO操作处理);
            b.
                CLOB:大文本数据(小说->数据)
                    存:先通过pstmt 的? 代替小说内容(占位符),再通过pstmt.setCharacterStream(2,reader,(int)file.length()); 将上一步的? 替换为 小说流,注意第三个参数需要时Int类型;
                    取:通过Reader reader=rs.getCharacterStream(“NOVEL”);将clob类型的数据 保存到Reader对象中,将Reader通过Writer输出即可;
                BLOB:二进制
                    与CLOB步骤基本一致,区别:getBinaryStream(...)getBinaryStream(...)    

14.JSP访问数据
    JSP就是在html中嵌套的java代码,因此java代码可以写在jsp中(<%...%>)
    导包操作:java项目:1.jar复制到工程中;2.右键该jar:build path ->add to build path
        web项目:jar复制到WEB-INF/lib 

15.JavaBean(简化代码、提高代码复用)
    刚才我们将 jsp中 登录操作的代码 转移到了LoginDao.java; 其中LoginDao类 就称之为JavaBean。
    JavaBean的作用:
        a.减轻jsp复杂度
        b.提高代码复用(以后任何地方的 登录操作,都可以通过调用LoginDao实现)
    JavaBean(就是一个java类)的定义:满足以下2点,就可以称之为JavaBean
        a.public 修饰的类,public 无参构造
        b.所有属性(如果有) 都是private,并且提供set/get(如果boolean 则get 可以替换成is)
    使用层面,Java分为2大类:
        a.封装业务逻辑的JavaBean(LoginDao.java封装了登录逻辑) 用于操作封装数据的JavaBean;
        b.封装数据的JavaBean(实体类,Student.java Person.java)对应于数据库中的一张表;
16.MVC设计模式:
    M:Model,模型:一个功能。(用JavaBean实现)
    V:View,视图:用于展示、以及与用户交互。(使用html、js、css、jsp、jquery等前端技术实现)
    C:Controller,控制器:接收请求,将请求跳转到模型进行处理;模型处理完毕后,再将处理的结果返回给 请求处。(可以用jsp实现,但是一般建议使用Servlet实现控制器)

17.Servlet:
    Java类必须符合一定的 规范:
        a.必须继承 javax.servlet.http.HttpServlet
        b.重写其中的doGet()或doPost()方法
            doGet():接收 并处理 所有get提交方式的请求
            doPost():接收 并处理 所有post提交方式的请求
        c.编写web.xml中的servlet映射关系(纯手工方式)
    Servlet要想使用,必须配置
        Servlet2.5:web.xml(纯手工方式)
        Servlet3.0:@WebServlet(不需要再web.xml中配置,但 需要在Servlet类的定义处之上编写 注解@WebServlet(“url-pattern的值”))
            匹配流程:请求地址 与@WebServlet中的值 进行匹配,如果匹配成功,则说明 请求的就是该注解所对应的的类;
    Web.xml:“/”代表项目根路径
    Jsp中的:“/”代表服务器根路径
    Servlet流程:
        请求-><url-pattern>->根据<servlet-mapping>中的<servlet-name>去匹配 <servlet>中的<servlet-name>,然后寻找到<servlet-class>,最终将请求交由<servlet-class>执行。
        Servlet生命周期(5个阶段):加载、初始化:init(),该方法会在Servlet被加载并实例化的以后执行,第一次访问servlet时会被执行(只执行这一次;可以修改为tomcat启动时自动执行);服务:service()->doGet()和doPost();销毁:destroy(),被系统回收时执行,关闭tomcat服务时,执行一次;卸载;
    eclipse中在src创建一个servlet,然后重写的doGet()、doPost()就可以。 (doGet()、doPost()只需要编写一个)

18.三层架构
    与MVC设计模式的目标一致:都是为了 解耦合、提高代码复用;
    区别,二者对醒目理解的角度不同。
    三层组成:
        表示层(URL,User Show Layer;视图层)
            前台:对应于MVC中的View:用于和用户交互、界面的显示(jsp、 js、 html 、css、 jQuery等web前端技术)
                代码位置:WebContent
            后台:对应于MVC中的Controller,用于 控制跳转、调用业务逻辑层(servlet(springMVC 、Structs2))
                位于xxx.servlet包中
                Servlet:一个Servlet对应于一个功能,因此 如果有增删改查(查询单个、查询全部)5个功能,则需要创建5个Servlet;
        业务逻辑层(BLL,Business Logic Layer;service层)
            接收表示层的请求 调用
            组装数据访问层,逻辑性的操作(增删改查,删:查+删)
            一般位于:xxx.service包(也可以称为:xxx.manager,xx.bll)
        数据访问层(DAL,Data Access Layer;Dao层)
            直接访问数据库的操作,原子性的操作(增删改查)
            一般位于xxx.dao包
    三层间的关系:
        上层 将请求传递给下层,下层处理后 返回给上层
        上层依赖于下层,依赖:代码的理解,就是持有成员变量 或者理解为: 有A的前提 是必须先有B(必须现有了数据库,才可能会存在DAO层,DAO依赖于数据库)
    三层优化
        加入接口
            建议面向接口开发:先接口->再实现类
            service、dao加入接口
            接口与实现类的命名规范
                接口:interface,    起名     I实体类Service
                            I实体类Dao
                实现类:implements,    起名     实体类ServiceImpl
                                实体类DaoImpl
            以后使用接口/实现类时,推荐写法:
                接口 x=new 实现类();
        DBUtil 通用的数据库帮助类,可以简化Dao层的代码量
            帮助类 一般建议写在 xxx.util包
            方法重构:将多个方法 的共同代码 提炼出来,单独写在一个方法中,然后引入该方法即可;

19.分页
    要实现分页,必须知道 某一页的 数据 从哪里开始 到哪里结束
    
    分页实现:(5个变量(属性))
        1.数据总数                (查数据库,select count(1)...)
        2.页面大小(每页显示的数据条数)        (用户自定义)
        3.总页数                    (程序自动计算)
        4.当前页(页码)                (用户自定义)
        5.当前页的对象集合(实体类集合)        (查数据库,分页SQL)

    oracle的分页查询语句:
    select * from(select rownum r,t.*  from(select s.* from student s order by sno asc) t ) where r>=(n-1)*10+1 and r <=n*10;

20.文件上传:
    a.在Apache下载Commons fileupload.jar包和Commons io.jar包,然后引入jar包;
    b.代码
        前台jsp:
            <input type="file" name="name"/>
            表单提交方式必须为post
            在表单中必须增加一个属性entype=“multipart/form-data”
        后台servlet:
            request.setCharacterEncoding(“utf-8”);
            response.setCharacterEncoding(“utf-8”);
            response.setContentType(“text/html;charset=utf-8”);

        注意的问题:上传的目录 有时会被删除;
            1.如果修改代码,则在tomcat重新启动时,会被删除
                原因是:当修改代码的时候,tomcat会重新编译一份class并且重新部署(重新创建各种目录)
            2.如果不修改代码,则不会被删除
                原因是:没有修改代码,class仍然是之前的class
            因此,为了防止 上传目录丢失:a.虚拟路径 b.直接更换上传目录 到非tomcat目录;
        限制上传:
            类型、大小;注意对文件的限制条件 写在parseRequest之前;

21.文件下载:不需要任何依赖jar
    a.请求(地址a  表单from),请求servlet;
    b.servlet通过文件的地址 将文件转为输入流  读到servlet中;
    c.通过输出流 将 刚才已经转为输入流的文件 输出给用户;
    注意:下载文件 需要设置2个 响应头;
    
    解决下载文件名中文乱码问题:
        edge:URLEcoder.encode(fileName,“UTF-8”)
        Firefox:给文件名 加:前缀(=?UTF-8?B)、String构造方法、Base64.encodebase64、后缀(?=);

22.EL:Expression Language,可以替代JSP页面中的java代码;
    传统的 在JSP中用java代码显示数据的弊端: 类型转换、需要处理null、代码掺杂 ->EL
        EL示例:${requestScope.student.address.schoolAddress};${域对象.域对象中的属性.属性.属性.级联属性}
    EL操作符:
        点操作符:    --使用方便
        中括号操作符[“”/‘’/ ]:    --功能强大:可以包含特殊字符(.    、 -),获取map属性,获取数组元素,获取变量值;
    EL表达式的隐式对象(不需要new 就能使用的对象, 自带的对象)
        a.作用域访问对象(EL域对象):pageScope  < requestScope  < sessionScope  < applicationScope
            如果不指定域对象,则默认会根据 从小到大的顺序 依次取值;
        b.参数访问对象:获取表单数据(超链接中传的值: a.jsp?a=b&c=d,地址栏中的值:a.jsp?a=b&c=d)(${param}相当于request.getParameter()、${paramValues}相当于request.getParameterValues())
        c.JSP隐式对象:pageContext
            在jsp中可以通过pageContext 获取其他的jsp隐式对象;因此 如果要在EL中使用JSP隐式对象,就可以通过pageContext间接获取,例如${pageContext.request}相当于通过get
Request()方法获取request对象;可是使用此方法,级联获取方法(同样方法获取其余对象及属性);即${pageContext.方法名去掉get和()并且将首字母小写}

23.JSTL:比EL更强大
    需要引入2个jar包:jstl.jar   standard.jar 
    引入tablib:<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix="c"%> 其中prefix=“c”:前缀
    核心标签库:通用标签库、条件标签库、迭代标签库
        a.通用标签库
            <c:set>赋值
            i:在某个作用域之中(4个范围对象),给某个变量赋值;<c:set  var=“变量名” value=“变量值” scope=“4个范围的作用域”/>相当于<%request.setAttribute(“name”,“zhangsan”);%>
            ii:在某个作用域之中(4个范围对象):
                给某个对象的属性赋值;<c:set  target=“${requestScope.student}” property=“sname” value=“zxs”/>(此种写法,不能指定scope属性)
                给map对象赋值;<c:set   target=“${requestScope.countries}”(对象) property=“cn”(对象的属性) value=“中国”(赋值)/>
            注意:<c:set/>可以给不存在的变量赋值;(但是不能给不存在的对象赋值)
            <c:out>方式:<c:out   value="${requestScope.countries}">显示
            <c:remove>方式:<c:remove  var=“a” scope=“request”>删除属性

            选择:
                if(boolean)单重选择
                    <c:if  test=“${10>2}” var=“result” scope=“request”>
                        真
                        ${requestScope.result}
                    </c:if>
                if...else if... 多重选择
                    <c:choose>
                        <c:when   test=“${requestScop.role=='老师'}”>老师代码...</c:when>
                        <c:when   test=“${requestScop.role=='学生'}”>学生代码...</c:when>
                        <c:when   test=“${requestScop.role=='...'}”>...代码...</c:when>
                        <c:otherwise>其他代码...</c:when>
                    </c:choose>
                注意:在使用test=“” 一定要注意后面是否有空格;
                    例如:    test="${10>2}"    true
                        test="${10>2} "    非true(false)
            循环:循环(迭代标签库)
                for(int i=0;i<5;i++)
                    <c:forEach begin="0" end="5" step="1" varStatus=“status”>${status.index} 内容...</c:forEach>
                for(String  str:names)
                    <c:forEach var=“str” items=“${requestScope.names}”>${str}</c:forEach>

23.过滤器:
    通配符
        dispatcher请求方式:
            REQUEST(常用):拦截HTTP请求get post
            FORWARD(常用):之拦截 通过 请求转发方式的请求
            INCLUDE:只拦截通过request.getRequestDispatcher(“”).include()、通过<jsp:include  page="..."/>此种方式发出的请求
            ERROR:只拦截<error-page>发出的请求
    过滤器中deFileter方法参数:ServletRequest
    在servlet中的方法参数:HttpServletRequest
    
    过滤器链
        可以配置多个过滤器,过滤器的先后顺序 是由<filter-mapping>的位置决定

24.监听器
    开发步骤:
        a编写监听器,实现接口
        b配置web.xml(个别不需要配置,例如:HttpSessionBindingListener、HttpSessionActivationListener)
    监听对象(主要三个对象):request、session、application
        a.监听对象的创建和销毁:
        request:ServletRequestListener
        session:HttpSessionListener
        application:ServletContextListener
        每个监听器 各自提供了2个方法:监听开始、监听结束的方法
        servletContext在servlet容器启动时 自动创建;
        b.监听对象中属性的变更
        request:ServletRequestAttributeListener
        session:HttpSessionAttributeListener
        application:ServletContextAttributeListener
        
25.session的钝化和活化:
    钝化:内存->硬盘
    活化:硬盘->内存
    session对象的四种状态:
        监听绑定和解绑:HttpSessionBindingListener    不需要配置web.xml
            a.session.setAttribute(“a”,xxx) 对象a【绑定】到session中
            b.session.removeAttribute(“a”) 对象a从session中【解绑】
        监听session对象的钝化、活化:HttpSessionActivationListener        不需要配置web.xml
            c.钝化
            d.活化
        如何钝化、活化:配置tomcat安装目录/conf/context.xml
        钝化、活化本质 就是序列化、反序列化:序列化、反序列化需要实现Serializable接口
    总结:钝化、活化 实际执行 是通过context.xml中进行配置 而进行。HttpSessionActivationListener只是负责 在session钝化 和 活化时 予以监听。

26.Ajax:异步js 和xml
    异步刷新:如果网页中某一个地方需要修改,异步刷新可以使:只刷新该需要修改的地方,而页面中其他地方 保持不变。例如:百度搜索框、视频点赞;

    实现:
        js:XMLHttpRequest对象
            XMLHttpRequest对象的方法:
                open(方法名(提交方式get/post),服务器地址,true):与服务器建立连接
                send():
                    get:send(null)
                    post:send(参数值)
                setRequestHeader(header,value):
                    get:不需要设置此方法
                    post需要设置:
                        a.如果请求元素中包含了 文件上传    setRequestHeader(“Content-Type”,“multiparty/form-data”)
                        b.如果不包含 文件上传        setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”)
            XMLHttpRequest对象的属性:
                readyState:请求状态    只有状态为4 代表请求完毕
                status:响应状态        只有200 代表响应正常
                onreadystatechange:回调函数
                responseText:响应格式为String
                responseXML:响应格式为XML

        jQuery:推荐方式
            $.ajax({
                url:服务器地址,
                请求方式:get/post,
                data:请求数据,
                success:function(result,testStatus){

                },
                error:function(xhr,errorMessage,e){

                }});
                $.get(
                服务器地址,请求数据,function(result){
                },
                预期返回值类型(string/xml)
                );
                $.post(
                服务器地址,请求数据,function(result){
                },
                预期返回值类型(string/xml/json)
                );
                $(xxx).load(
                服务器地址,请求数据,function(result){
                },
                预期返回值类型(string/xml/json)
                );
                load:将服务端的返回值 直接加载到$(xxx)所选择的元素中;
                $.getJSON(
                服务器地址,JSON格式的请求数据{“mobile”,$mobile},function(result){
                }
                )


    


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值