java ee 笔记

=============JSP===============

 

cookies生存期限就到你关闭浏览器为止

       cookies 在tomcat 关闭会清除,reload也会清除

session默认是20分钟

流程:

  1. 启动tomcat
  2. 客户端浏览器发请求
  3. tomcat在webapp或者虚目录下找到项目,再找到请求的jsp
  4. 第一次:将jsp 变成 .java, .java---> .class
  5.  

【JSP指令】:

Jsp指令的格式:<%@指令名 attr1=””attr2=””%>,一般都会把JSP指令放到JSP文件的最上方

       (1)page:page指令,用于定义jsp页面级的其他元素特性

       (2)include:include 指令,用于嵌入另一个文本文件的内容到本页面

              [静态包含]

              *它和RequestDispatcher的include()方法的功能相似!

               *<%@include%>它是在jsp编译成java文件时候完成的!他们共同生成一个.java文件,然后编译成一个.class

               *RequestDispatcher.include();是一个方法,包含和被包含的是两个servlet,

                     他们只是把响应的内容在运行时合并了!!!

       (3)taglib:标记库指令,用于引入第三方jsp扩展标记类库

              >prefix:指定标签库在本页面中的前缀!由我们自己取名字

              >uri:指定标签库的位置

              ><%@taglib prefix=”pre” uri=”text”%> 使用:<pre:text>

*pageEncoding 和 contentType

>pageEncoding 服务器把jsp编译成.java时需要使用pageEncoding

>contentType:它表示添加一个响应头:Content-Type!等同于response.setContentType(“text/html;charset=utf-8”);

>pageEncoding 和 contentType 如果只设置了一个,另一个的值和设置了的相同

>如果两个属性都没有设置,默认为iso

       *errorPage 和  isErrorPage

       >errorPage:当前页面如果抛出异常,那么转发到哪一个页面,由errorPage指定

       >isErrorPage:它指定当前页面是否为处理错误的页面!当issErrorPage为true时这个错误页面响应的状态码是500!!!而且这个页面可以使用九大内置对象Exception

【JSP动作标签】

       这些JSP的动作标签,与html提供的标签有本质的区别。

       *动作标签是由tocat(服务器)来解释执行的!它和Java代码一样,都是在服务器端执行的。

       *html由浏览器来执行

       *<jsp:forward>:转发!他和requestDispatcher的forward一样

       *<jsp:include>:请求包含! RequestDispatcher的include 一样,自然和前面的include指令不同。

       *传递参数  request域中

例子:<jsp:inlucde page=”/b.jsp”>

              <jsp:param value=”abc” name=”name”/>

       </jsp:include>

*<% User user = new User(); %>

 

*<jsp:userBean id="user1" class="cn.itcast.domain.User" scope="request"/>

       >创建或查询bean

       >放到与相应对象中

*<jsp:setProperty property=”name” name=”user1” value=”admin”/>

       >设置user1 的 name属性值为admin

*<jsp:getProperty property=”name” name=”user1”/>

       >返回user1的name属性值

 

      

 

 

【jsp 内置对象】

(1)request

(2)response

(3)session

(4)application 应用服务器对象

(5)page:JSP本身页面类对象

(6)pageContext:页面级环境变量,

(7)out:输出对象

(8)exception:异常对象

(9)config:配置对象

*servlet三个域对象,jsp四个域对象

       >ServletContext(application):整个应用程序

       >session(session):整个会话

       >request(request):一个请求链

       ???>pageContext(page):一个Jsp页面!!!(一个顶九个)

              >这个域是在当前jsp页面和当前jsp页面中使用的标签之间共享数据!

              >域对象

              >代理其他域:pageContext.setAttribute(“xxx”,’xxx’,PageContext.SESSION_SCOPE);

              向session域中存数据。

              >全域查找:pageContext.findAttribute(“xxx”);从小到大查找(request,session,servletContext),查找有优先级!

              >获取其他8个对象

* jsp域对象范围

从小到大:

>pageContext

>Request

>Session

>application

【EL表达式】

1.最常用的表达式是

>全域查找${xxx}

       查找是按范围从小到大进行,找不到返回 ””(空字符串)

>范围查找:${pageScope.xxx}

${requestScope.xxx}

${sessionScope.xxx}

${applicationScope.xxx}

 

2.El 是JSP内置的表达式语言!

       *jsp2.0开始,不让在使用java脚本,而是使用el表达式和动态标签来代替java脚本

       *EL代替的是 <%= …. %>,也就是说,EL只能做输出

3.11个内置对象

       其中10个是map,pageContext不是map,它一个顶九个

>pageScope

>requestScope

>sessionScope

>applicationScope

>param:Map<String,String>类型,param对象可以用来获取参数,和request.getParameter()方法相同

>paramValues:paramValues是Map<String,String[]>类型,当一个参数名有多个对应的参数时可以使用它。

>header:对应请求头,map,key参数名称,values是单个头值,适用于单个请求头值

>headerValues

       同上,只不过是适用于单头,多值

>initParam

>cookie 它是一个Map<String,Cookie>类型,key是cookie的name,value是cookie对象

>pageContext

EL函数库

El函数库是第三方对EL的扩展,我们现在学习的el函数是jstl添加的。

1.需要导入<%@ taglib prefix=”fn” uri=”http://java.sun.com/jsp/jstl/functions”%>

2. ${fn:length(arr)}

${fn:toLowerCase(“Hello”)}

…详情在day12

 

自定义函数库

*写一个java类,类中定义0-N个方法,但必须是static方法,而且有返回值

*在WEB-INF目录下创建一个tld文件

       <function>

       <name>fun</name>

<function-class>cn.itcast.fn.MyFunction</function-class>

<function-signature>java.lang.String fun()</function-signature>

</function>

*在jsp页面导入并使用自定义的标签

<%a taglib prefix=”it” uri=”/WEB-INF/tids/itcast.tld”%>

${ it:fun()}

模型(M)-视图(V)-控制器(C)

mvc使得应用程序的输入输出分开

       mvc不是java独有的

model   view    controller

M –model 模型(自己写代码)

V- view    视图(JSP)

C – cotroller 控制器(Servlet)

javaWeb三层架构

WEB层  -> 与Web相关的内容(Servlet)

业务层  à  业务对象(Service)

数据层  à 操作数据库 (DAO  Data  Access  Object) 所有对数据库的操作,不能跳出DAO之外

 

Dao

Domain

Service

Web.servlet

===============================

session:1.保存用户登陆信息2.购物车

web项目中,src=“”,src是从webroot开始算

注意:访问子文件夹中的Jsp页面时,url要写成这样:"T/xx.jsp",不要在最前面加'/',会调到父级目录.

-------------------------

做项目的步骤:

1.界面(模仿)

2.数据库(表的设计)[通过功能猜出来](用户表)(商品表)

       insert into goods (goodsName,goodsIntro,goodsPrice,goodsNum,publisher,photo,type)

       values

       ('黑白森林','这是一部好书',59,1,'香港嘉禾出品','01.jpg','香港电影');

3.建立web工程

dw做页面

 

//订单表设计

create table orders(

       ordersId int primary key auto_increment,

       userId int,

       orderDate datetime,

       payMode varchar(30),

       isPayed char,

       totalPrice decimal(10,2)

      

)

 

create table orderGood(

       ordersId int,

       goodsId int,

       nums int

)

Java EE过滤器API

javax.servlet.Filter接口

1.public void init(FilterConfig filterConfig)throws ServletException

2.public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws

       IOException,ServletException

3.public void destroy()

javax.servlet.FilterConfig接口

1.public String getInitParameter(String name)

2.public Enumeration getInitParameterNames()

3.public String getFilterName()

4.public ServletContext getServletContext()

 

Java EE监听器类型和事件类型

ServletContextListener   ServletContextEvent

servletContextAttributeListener ServletContextAttributeEvent

HttpSessionListener HttpSessionEvent

HttpSessionActivationListener  HttpSessionEvent

HttpSessionBindingListener    HttpSessionBindingEvent

ServletRequestListener    ServletRequestEvent

ServletRequestAttributeListener     ServletRequestAttributeEvent

 

//图片映射代码

<img src = "images/apple.jpg" alt = "apple" usemap = "#map1" height = "100" width = "100"/>  

        <map name = "map1">  

            <area shape = "rect" coords = "0,0,50,50" href = "ImageDemo.html">  

            <area shape = "rect" coords = "50,50,100,100" href = "http://www.google.com/">  

            <area shape = "rect" coords = "0,50,50,100" href = "http://www.baidu.com/">  

            <area shape = "rect" coords = "50,0,100,50" href = "http://www.renren.com/">  

        </map>  

 

 

Struts :基于mvc的web框架    struts-comfig.xml  这是struts的一个核心文件

       web服务器

       ActionServlet(总控制器/总司令)

       表单(actionForm),用于存放数据

       action(分控/小队长)

       model(java类[Service]/士兵)

       jsp页面

 

 

==============tomcat&http==================================

配置外部应用:

方法1:conf/server.xml  打开这个文件,找到<Host>元素,在其中添加<Context>元素,代码如下:

 

<Host name=”localhost” appBase=”webapps”

         unpackWARs=”true” autoDeploy=”true”>

         <Context path=”itcast_hello” docBase=”C:/hello”/>

</Heost>

                                

  1. Path:指定当前应用的名称
  2. DocBase:指定应用的物理位置
  3. 浏览器访问路径:http://localhost:8080/itcast_hello/index.html.

方法2:conf/catalane/localhost

              在该目录下面创建itcast_hello.xml文件

              里面代码如下:<Context docBase=”C:/hello”/>

  1. 文件名:指定当前应用的名称
  2. docBase:指定应用的物理位置
  3. 浏览器访问路径:http://localhost:8080/itcast_helo/index.html

 

响应码:

302:重定向 两个请求,

304: 较为复杂,比较最后修改时间,如果没有变,服务器发送这个

‘自动刷新响应头’,浏览器会在3秒之后请求url

Refresh:3;url=http://www.baidu.com 定时刷新

 

案例:

  • 定时刷新:设置Refresh头,把它理解成定时重定向
  • 禁用浏览器缓存:Cache_Control,pragma,expires
  • <meta>标签可以代替响应头:<meta http-equiv=”Content-Type” content=”text/html”;charset=”UTF-8”>

重定向方法:

  • SendRedirect(str)方法   str=请求url    /项目名+访问名

 

 请求参数:由客户端发送给服务器的!有可能是在请求体的(post),也有可能是在URL之后

getParameter(String name):获取指定名称的请求参数值,也适用于单值请求参数

 

 

 

 

 

 

 

 

 

 

 

==============================Servlet=============================

当第一次请求这个Servlet时候,Servlet创建

服务器关闭,Servlet结束;

ServletConfig:Servlet的一些信息,

ServletRequest请求的所有信息都封装到这个对象中

ServletResponse 发送

 

Servlet中可以创建无状态的成员

或者只读状态的成员

本质原因:Servlet是线程不安全的;         

 

 

请求转发: A请求发出到AServlet,  Aservlet 请求转发或包含Bservlet

有时候一个请求需要多个Servlet协助才能完成,

RequestDispatcher rd= request.getRequestDispatcher(“/BServlet”);

请求转发>rd.forward(request,reponse);

请求包含>rd.include(request,reponse);

一个请求跨多个Servlet,需要使用转发和包含

>请求转发:由下一个Servlet完成响应体!当前Servlet可以设置响应头!(留头不留体)

>请求包含:由两个Servlet共同完成未完成响应体!(都留)

>无论是请求转发,还是请求包含,都在一个请求范围内!使用同一个request和reponse

【请求转发和重定向区别】

  1. 请求转发是一个请求一次响应,而从重定向是两次请求两次响应
  2. 请求转发地址栏不变化,而重定向会显示后一个请求的地址
  3. 请求转发只能转发到本项目其他Servlet,而重定向不止能到本项目其他Servlet,还能定向到其他项目
  4. 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出RequestURI,即项目名+Servlet路径

 

 

 

【编码之响应解码】

Response.setContentType(“text/html;charset=utf-8”);

这句话设置了响应编码即UTF-8格式,浏览器即用utf-8编码

它还设置了服务器使用UTF-8来解码;

【编码之请求编码

tomcat8之后,不需要这样弄

客户端传递的数据编码有两种情况:

  1. 用户直接在地址栏中输入参数(gbk)
  2. 用户在页面中点击表单或者链接(utf-8),如果页面是utf-8编码,则传递的参数就是UTF-8编码。

默认tomcat使用ISO处理请求参数,

  1. Post请求:只需在获取参数之前调用request的setCharacterEncoding(“utf-8”);即可
  2. Get请求:Get请求的参数传递到服务器,编码默认是ISO。。。

可以在tomcat配置文件中修改默认Get请求的编码,但是不让用,以为客户不一定适用tomcat作为服务器。

String name= request.getParameter(“name”);//乱码

Byte[] bytes = name.getBytes(“ISO-8859-1”);

Name= new String(bytes,“utf-8”);

---注意:tomcat8之后,get请求参数编码默认是UTF-8

URL编码

       表单的类型:Content-Type: application/x-www-form-urlencoded,就是把中文转换成%后面跟随两位的16进制。

 

*它不是字符编码

*它是用来在客户端与服务器之间传递参数用的一种方式

*URL编码需要向指定一种字符编码,把字符串解码后,得到byte[],然后把小于0的字符+256,在转换成16进制。前面在添加一个%。

*Post请求默认就是用URL编码!tomcat会自动使用URL编码

*URL编码:String username= URLEncoder.encode(username,”utf-8”);

*URL解码:String username= URLDecoder.encode(username,”utf-8”);

Get请求中的中文没有URL编码,可能会丢失字节

使用表单,表单自动使用URL编码,服务器自动识别URL编码,然后解码。

【路径】

  1. Web.xml中,<url-pattern>路径  [Servlet映射路径]

>要么以“*”开头,要么以“/”开头

 *  转发和包含路径

       >以“/”开头:相对于当前项目路径,例如:http://localhost:8080/mypro/

       >不以“/”开头:相对于当前Servlet路径。。

*   重定向路径(setRedirect())

>以“/”开头:相对于当前主机,例如:http://localhost:8080/ ,所有要自己手动添加项目名

*   页面中超链接和表单路径

       >与重定向相同,以“/”开头,相对当前主机路径

       >不以“/”开头,相对当前页面所在目录的路径

              例子:<a href=”AServlet”/>  http://localhost:8080/day10/html/form.html

*   ServletContext获取资源路径

       >相对于当前项目目录,即index.jsp所在目录,WebContent下

* ClassLoader获取资源路径

>相对于classes目录或者 SRC文件夹路径(加’/’错了,为什么要加/)

 

*  Class获取资源路径

       >以“/”开头,相对于classes目录

       >不以“/”开头,相对于当前   .class  文件所在目录

<head>

<base target = “main”>它的作用是为本页面所有的表单和超链接指定显示内容的框架

</head>

  1. 在引入js文件的时候,src = “/test.js”  这样引入的时候是以http://localhost:8080/test.js 引入的,加上’/’  相对于服务器目录

【Cookie】

*原始方法

       >使用response发送Set-Cookie响应头

       >使用request 获取 Cookie请求头

*便捷方法

       >使用reponse.addCookie()方法向浏览器发送Cookie

       >使用request.getCookies()方法获取浏览器归还的Coolies

*生命

       默认cookies的MaxAge=-1,意思是[cookies生存期限为你关闭浏览器为止,只在内存中存活]

       cookies 在tomcat 关闭会清除,reload也会清除

       MaxAge 以秒为单位

       Maxage>0:浏览器把cookie保存到客户机的硬盘上,即cookie的最大保存时间。

       Maxage=0:浏览器直接删除这个Cookie

       Maxage<0:cookie只保存在内存中,浏览器一关,cookie即被清除

*路径

       >cookie的path并不是设置这个cookie在浏览器的保存路径

       >cookie的path由服务器创建cookie时设置

       >当浏览器访问服务器某个路径时,需要归还哪些cookie给服务器,由这个Cookie的path决定,如果 访问路径 包含这个cookie的path,则带上它;

       >cookie如果不设置,即path是访问路径的父路径;

例如在访问 /day11/jsps/a.jsp时,响应了cookie,没有设置path,默认path是/day11/jsps

*cookie的域

       >domain用来指定cookie的域名,当多个二级域中共享cookie时才用

       >例如:www.baidu.com zhidao.baidu.com news.baidu.com之间共享cookie时可以使用

       >设置domain为 cookie.setDomain(“.baidu.com”);

       >设置path为: cookie.setPath(“/”);

 

【session】

1.HttpSession是servlet三大域对象之一(request,session,application(ServletContext));

HttpSession是由javaWeb提供的,用来会话跟踪的类,session是服务器对象,保存在服务器端。

  1. session的作用

会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束。

*服务器为每一个客户端创建session对象,session就好比客户在服务器端的账户,他们被服务器保存到一个Map中,这个map被称为session

*服务器不会马上给你创建Session,在第一次获取session时候创建

*原理:创建session时,服务器会返回一个sessionID的cookie, 当客户端拿着这个cookie再次访问服务器时,服务器通过SEssionID找到session,如果没有找到,创建新的session。

(访问servlet,如果没有调用session的获取方法,session服务器不会创建,

访问Jsp中,默认需要得到session,即session马上创建,客户端得到含有jsessionID的cookie);

 

*request.getSession(false); request.getSession(true); request.getSession();

       >后两个方法是相同的

>第一个方法:如果session缓存中(cookie不存在)不存在session,,返回null,不会创建session

 

*URL重写(理解) 感觉鸡肋

      Session是基于cookie,如果客户端禁用了cookie,服务器无法通过sessionID获取相应的session,下面的方法在cookie失效时会在所有的连接,表单提交中添加SessionID参数,以便让服务器得到相应session
         public java.lang.String encodeURL(java.lang.String url)
        response.encodeURL(“/day11/AServlet”);

>它会查看cookie是否存在,如果不存在,在指定的url后添加jsessionid的参数

>如果cookie存在,不做处理

 

 

JSTL标签库

  1. JSTL是阿帕奇对EL表达式的扩展(也就是JSTL以来EL),JSTL是标签语言!
  2. lib目录下存放jstl的JAR包jstl-1.2.jar

四大库

Core:核心库

*<c:out>:输出

>value:可以是字符串,也可以是EL表达式

>default:当要输出的内容是NULL时,会输出default的内容

>escapeXml:默认是Ture,表示输出时转义特殊字符

*<c:set>设置(创建域的属性)

>var :变量名

>value:变量值,可以为EL

>scope:默认page, 可选:page,request,session,application

*<remove>:删除域变量

>var:变量名

>scope:如果不给出,删除所有域中该名称的变量,给出了域,只删除域中

*url

       >value:指定一个路径,他会在路径前面自动加上项目名

       >子标签:<c:param>,用于url后添加参数

       >var:指定变量名,一旦添加了这个属性,那么url标签就不会输出到页面

       而是把生成的URL保存到域中

       >scope:与var一起使用,用于保存url

       <c:url value=”/index.jsp”/> ,它会输出:/day13/index.jsp

<c:url value=”/AServlet”>

<c:param name=”un” value=”abc”/>

<c:param name=”ps” value=”123”/>

</c:url>输出:/day13/AServlet?un=abc&ps=123

参数中包含中文会自动使用URL编码

*if:对应java的if语句

       *<c:if test=”布尔类型”></c:if>

*choose:对应java中的if/else if /else 结构

*forEach

       >var:循环变量

       >begin:设置循环变量从几开始

       >end:设置循环变量到几结束

       >step:设置步长,默认是1

>items:后面的字符串不能有多余的空格,否则出错

例子:items后不能空格,错误输出

<c:forEach items=${arr}  var=”str”>

${str}

</c:forEach>

**状态变量的属性

***count:  int 类型,当前已遍历元素的个数

***index:  int类型,当前元素的下标

***first: boolean类型,是否为第一个元素

***last: boolean类型,是否为最后一个元素

***current:Object类型,表示当前项目

<forEach varStatus=”vs”…>

       ${vs.index}

       </c:forEach>

Fmt:格式化:日期,数字

        1. 格式化时间

<%

Date d = new Date();pageContext.setAttribute(“d”, date);

%>

<fmt:formatDate value=”${d}” pattern=”yyyy-MM-dd HH:mm:ss”/>

               2 . 格式化数字

               <%

               pageContext.setAttribute(“d1”,23.2);

pageContext.setAttribute(“d2”,23.991);

%>

<fmt:formatNumber value=”${d1}” pattern=”0.00”/><br/>

<fmt:formatNumber value=”${d2}” pattern=”#.##”/><br/>

Ps:如果指定位数不够,0.000会补位,#.###不会补位

JSTL(fn函数)  

 首先,我们要在页面的最上方引用:

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

 

下面是JSTL中自带的方法列表以及其描述:

 

fn:contains(string, substring)

假如参数string中包含参数substring,返回true

例如:<c:if test="${fn:contains(name, searchString)}">

 

fn:containsIgnoreCase(string, substring)

假如参数string中包含参数substring(忽略大小写),返回true

例如:<c:if test="${fn:containsIgnoreCase(name, searchString)}">

 

fn:endsWith(string, suffix)

假如参数 string 以参数suffix结尾,返回true

例如:<c:if test="${fn:endsWith(filename, ".txt")}">

 

fn:escapeXml(string)

将有非凡意义的XML (HTML)转换为对应的XML character entity code,并返回

例如: <字符应该转为&lt; ${fn:escapeXml(param:info)}

 

fn:indexOf(string, substring)

返回参数substring在参数string中第一次出现的位置

${fn:indexOf(name, "-")}

 

fn:join(array, separator)

将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。

${fn:join(array, ";")}

 

fn:length(item)

返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。假如是String类型,返回值是String中的字符数。

${fn:length(shoppingCart.products)}

 

fn:replace(string, before, after)

返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果

${fn:replace(text, "-", "&#149;")}

 

fn:split(string, separator)

返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素

${fn:split(customerNames, ";")}

 

fn:startsWith(string, prefix)

假如参数string以参数prefix开头,返回true

<c:if test="${fn:startsWith(product.id, "100-")}">

 

fn:substring(string, begin, end)

返回参数string部分字符串,从参数begin开始到参数end位置,包括end位置的字符

${fn:substring(zip, 6, -1)}

 

fn:substringAfter(string, substring)

返回参数substring在参数string中后面的那一部分字符串

${fn:substringAfter(zip, "-")}

 

fn:substringBefore(string, substring)

返回参数substring在参数string中前面的那一部分字符串

${fn:substringBefore(zip, "-")}

 

fn:toLowerCase(string)

将参数string所有的字符变为小写,并将其返回

${fn.toLowerCase(product.name)}

 

fn:toUpperCase(string)

将参数string所有的字符变为大写,并将其返回

${fn.UpperCase(product.name)}

 

fn:trim(string)

去除参数string 首尾的空格,并将其返回

${fn.trim(name)}

 

 

Sql;过时

 

Xml:过时

 

自定义标签

步骤

*标签处理类(标签其实也是一个对象,需要类)

SimpleTag接口

Void doTag()  每次执行标签都会调用这个方法

JspTag getParent()  非生命周期方法

Void setParent(JspTag) 

Void setJspBody(JspFragment);

Void setJspContext(..)

*tld文件,它是一个xml

<tag>

<name>a</name>  指定当前标签的名称

<tag-class>cn.itcast.tag.MyTag1</tag-class> 标签处理类

<body-content>empty</body-content>  指定标签体的类型,当前使用空标签(没有标签体 ,类似<br/>)

</tag>

*页面中导入<%@ taglib …%>

<%@ taglib prefix="r" uri="/WEB-INF/tlds/tag1.tld" %> 指定tld文件的位置

标签体类型

<body-content>元素的可选值有

*empty  无标签体

*JSP     传统标签支持它,SimpleTag已经不再支持<body-content>JSP</body-content>.标签体内容可以是任意的东西EL,JSTL,<%==%>,<%%>,以及HTML

*scriptless  :标签提内容不能是java脚本,但可以说EL,JSTL等。在SimpleTag中,如果需要有标签体,那么就是用这项

*tagdependent   :标签体内容不做运算,由标签处理类自行处理,无论标签体内容是EL,JSTL,JSP,都不做计算。这个选项几乎没有人选。

标签处理类需要

*获取标签体对象:JspFragment jspBody = getJspBody()

*把标签体内容输出到页面;jspBody.invoke(null);

*tld中指定标签类型:scriptless

*不执行标签下面的页面内容

       如果希望在执行了自定义标签后,不再执行jsp页面下的东西,那么就需要在doTag方法中抛出一个跳过页面的异常:SkipPageException

代码:throw new SkipPageException();---à跳过页面异常

标签属性

步骤

  1. 给你的标签处理类添加属性
    1. 属性至少要有一个Set方法,这个set方法和其他set方法一样,在doTag方法之前,会被tomcat调用。
  2. 在TLD文件对属性进行配置

<attribute>

         <name>test</name>       属性名

         <required>true</required>  属性是否必须要传

         <rtexprvalue>true</rtexprvalue> 运行时参数是否可以是EL表达式

</attribute>

 

 

 

 

数据库连接池

  1. 池参数

初始大小:10个

最小空闲连接:3个

增量:一次创建的最小单位:5个

最大空闲连接数:12 个

最大连接数:20个

最大等待时间:1000毫秒

 

实现的接口

连接池必须要实现的接口:javax.sql.DataSource接口!

连接池返回的Conection对象,他的close()方法是把它的连接归还给连接池

 

Dbcp连接池

   Day18文件夹有源码极其jar

  

C3p0连接池

Day18文件夹有源码极其jar

 

Webpro2àconnPool有使用DEMO

 

 

分页

页面的数据都是由Servlet传递过来的

Servlet:

  1. 当前页:pageCode ,  pc
      1. Pc:如果页面没有传递当前页码,默认是1
  2. 总页数:totalPages,   tp   不存在属性,只有get方法
      1. Tp:总记录数 /  每页记录数
  3. 总记录数:totalRecord,  tr
      1. Tr:  dao 中获取
  4. 每页记录数:业务数据或叫系统数据 pageSize,   ps,自定义:10
  5. 当前页数据:beanList
  6. URL: 这个是分页的重点,用于保存用户提交的搜索条件,当翻下一页时候,条件自动加到URL后面 ;条件表单的提交只能用GET,否则获取不到URL参数

把分页数据封装到一个javaBean中,PageBean

Class PageBean

{…}

 

分页在各层中的处理

  1. 页面:给出分页相关的链接们
    1. 通常需要给Servlet传递pc,  
  2. Servlet:创建PageBean对象,给PageBean对象所有属性赋值,传递给页面
  3. Service:略
  4. Dao:
    1. TR:总记录
    2. beanList:页面数据

显示分页页码

1 2 3 4 5 6 7 8 9 10

  1. 最多显示多少个页码!定为10
  2. 当前页在页码列表中的位置,定为6

只需要当前页码pc,就可以推算出begin 和  end

10 11 12 13 14 (15) 16 17 18 19

  1. 如果总页数小于等于(列表长度)10,显示begin=1,end=总页数
  2. 否则,使用计算公式来计算;begin=pc-5,  end = pc + 4;
      1. 头溢出,当begin<1时,begin=1
      2. 尾溢出,当end>tp,  end = tp;
  3. 在超链接中保留参数

当使用多条件查询后,然后再点击第二页时,这个第二页超链接没有条件,

所以会丢失条件,所以我们需要在页面是所有链接都保留条件

      我们要把条件以一个字符串的形式保存到PageBean的URL中,这个任务交给Servlet

 

 

 

页面静态化

1说 明

你到”当当”搜索最多的是什么分类,没错,就是java分类!你猜猜看,你去搜索java分类的时候,当当会去查询数据库! 但现在问题是,其实每天都有很多人去搜索java分类的图书,每次都要去访问数据库,这回又性能上的缺失!如果是访问静态的HTML页面就快多了!静态页面本身就比动态页面快很多倍!!而且动态页面还要请求数据库,这会降低速度!

 

页面静态化例子:day21_1

页面静态化需要对某一个Servlet进行过滤

即需要一个Filter       Filter中需要替换掉Response,已达到生成静态页面的目的

 

 

 

文件上传下载

上传

上传对表单限制

    1. Method=”post”
    2. enctype=”multipart/form-data”
    3. 表单中需要添加文件表单项:<input type=”file” name=”xxx”/>
  1. 上传对Servlet的限制
    1. Request.getParametere(“xxx”);这个方法在表单为enctype=”multipart/form-data”时,它作废了。它永远都返回NULL。
    2. 可以用SerrvletInputStream request.getInputStream();包含整个请求的体

 

 ---

多部件表单的体

  1. 每隔出多个部件,即一个表单项一个部件
  2. 一个部件中自己包含请求头和空行,以及请求体
  3. 普通表单项:
    1. 1个头:Content-Disposition: 包含name=”xxx”,即表单项名称。
    2. 体就是表单项的值
  4. 文件表单项
    1. 俩个头:
    2. Content-Disposition:包含name=”xxx”,即表单名称:还有一个filename=”xxx”,例如: image/pjpeg,表示上传的是图片,图上中JPG扩展名的图片
    1. 体就是上传文件的内容

上传三步

Commons-fileupload

       *commons-fileupload.jar

       *commons-io.jar

这个小组件,它会帮我们解析request中的上传数据,解析后的结果是一个表单项数据封装到一个FileItem对象中。

  1. 相关类

*工厂:DiskFileItemFactory

*解析器:ServletFileUpload

*表单项: FileItem

1).创建工厂   DiskFileItemFactory factory = new DiskFileItemFactory();

2).创建解析器: ServletFileUpload sfu = new ServletFileUpload(factory);

3).使用解析器来解析request, 得到FileItem集合

       List<FileItem> fileItemList = sfu.parseRequest(request);

  1. FileItem
    1. Boolean   isFormField();是否是普通表单项,true则是
    2. String getFieldName(); 返回当前表单项的名称
    3. String getString(String charset);返回表单项的值;
    4. String getName();放回上传的文件名称
    5. Long getSize();返回上传文件的字节数
    6. InputStream getInputStream();返回上传文件对应的输入流
    7. Void write(File file);把上传的文件内容保存到指定的文件中,如果文件已存在,则替换,如果不存在,则新创建一个.
    8. String getContentType();得到上传文件类型

细节:

详情在day22.docx

  1. 把上传的文件保存到WEB-INF文件下
    1. 防止用户攻击
  2. 文件名称(完整路径,文件名称)
    1. 浏览器上传的文件名称可能是文件的完整路径
  3. 中文乱码问题
    1. 上传的文件名称包含中文,需要设置编码,commons-fileupload组件为我们提供了一种设置编码的方式,还有一种我们熟悉的

*request.setCharacterEncoding(string )

*fileUpload.setHeaderEncdoing(String):这种方式的优先级比较高

       4. 上传文件同名问题

       通常我们会把用户上传的文件保存到uploads目录下面,但如果用户上传了相同名称的文件,这会出现覆盖现象。处理这一问题的方法是使用UUID生成唯一的名称,然后在使用‘_’连接文件上的原始名称。

5.一个目录不能存放过多的文件

    1. 需要使用算法来打散
      1. (哈希打散)

6.上传单个文件的大小限制

    1. Sfu.setFileSizeMax(100 * 1024); 限制单个文件大小100kb
    2. 如果上传的文件超出限制,在parseRequest方法执行时,会抛出

异常:  FileUploadBase.FileSizeLimitExceededException

 

7. 上传文件的总大小限制

>sfu.setSizeMax(1024 * 1024) ;//限制整个表单的大小1M

>如果上传的文件超出限制,在parseRequest方法执行时候,会抛出异常!

FileUploadBase.SizeLimitExceededException

8. 缓存大小和临时目录

*缓存大小:超出多大,才向硬盘保存!默认为10kb

       在创建Factory的时候给定

*临时文件:向硬盘的什么目录保存

        在创建Factory的时候给定

 

 

 

下载

下载就是向客户端响应字节数据

原先我们向客户端响应的都是html  字符数据

现在我们把文件变成一个字节数组,使用response.getOutputStream();来响应给浏览器。

下载要求:

       *两个头,一个流

       >Content-Type:你传递给客户端的文件是什么MIME类型,例如:image/pjpeg

              *利用servletContext获取mime类型

       >Content-Disposition:它的默认值:inline,表示在浏览器窗口中打开。

              *应该设置为:attachment;filename=xxx  ;表示浏览器弹出一个下载框

                     文件名称:xxx

       >流:要下载的文件数据!

 

 

 

细节

       >显示 在下载框中的中文名字会 乱码

       *FireFox:  Base64  编码

       *其他大部分浏览器都是用 :  URL编码

通用方案:filename = new String(filename.getBytes(“GBK”), “iso-8859-1”);

JavaMail

邮件协议

 

(day22)详情

发邮件就是从客户端把邮件发送到客户服务器,收邮件是把邮件服务器的邮件下载到客户端

邮件协议概述:

       与http相同,收发邮件也是需要传输协议的

       *SMTP: (simple Mail Transfer  Protocol, 简单邮件传输协议) 发邮件协议

       * POP3 : (Post  office  protocol version  3,邮局协议第三版)收邮件协议

       * IMAP: (Internet Message Access  Protocol,因特网消息访问协议) 收发邮件协议

邮件服务器名称

       Smtp服务器的端口号是25,服务器名称是 smtp.xxx.xxx

       Pop3服务器的端口是110 ,服务器名称是 : pop3.xxx.xxx

       例如:163 :    smtp.163.com 和  pop3.163.com

       126:         smtp.126.com 和  pop3.126.com

       Qq:         smtp.qq.com  和  pop3.qq.com

       Sohu:       smtp.sohu.com 和 pop3.sohu.com

       Sina:       smtp.sina.com  和 pop3.sina.com

 

 

JavaMail

导包

*mail.jar

*activation.jar

核心类:session

       *如果你得到了它,表示已经和服务器连接上了,与Connection的作用相似

得到session,需要使用session.getInstance(properties, Authenticator)需要properties  和

Properites props = new Properites();

props.setProperty(“mail.host”,”smtp.163.com”);

props.setProperty(“mail.smtp.auth”,”true”);

Authenticator auth = new Authenticator() {

       Protected PasswordAuthentication getPasswordAuthentication(){

       Return new PasswordAuthentication(“itcast_cxf”,”itcast”);

}

};

 

Session session = Session.getInstance(props, auth);

MimeMessage

       *表示一个邮件对象,你可以调用它的setFrom(),设置发件人,设置收件人,

设置主题,设置正文

MimeMessage  msg = new MimeMessage(session);

TransPort

       *它只有一个功能,发邮件!: TransPort.send(msg);

 

 

 

 

 

 

 

Ajax

       (day23)

       它是asynchronous   javascript  and   xml; 异步的js  和  xml

       它能使用js访问服务器,而且是异步访问

       服务器给客户端的响应一般是整个页面,一个html完整页面!但在ajax中以为是局部刷新,那么服务器就不用在响应整个页面!而只是数据!

              >txt:纯文本  

              >xml:

              >json: 它 是js提供的数据交换格式,在ajax最受欢迎

       *异步响应和同步响应

       *同步

       >发送一个请求,就要等待服务器的响应结束,然后才能发第二个请求!中间这段时间有一点卡

       >刷新的是整个页面

       *异步

       >发一个请求,无需等待服务器响应,然后就可以发第二个请求!

       >可以使用js接受服务器的响应,然后使用js来局部刷新

Ajax发送异步请求(四步操作)

第一步(得到XMLHttpRequest)

*ajax其实只需要学习一个对象: XMLHttpRequest,如果掌握了它,就掌握了ajax

*得到XMLHttpRequest

>大多数浏览器都支持:var  xmlHttp = new XMLHttpRequest();

>IE6.0:               var   xmlHttp = new ActiveXObject(“Msxm12.XMLHTTP”);

>IE5.5及其更早:var xmlHttp = new ActiveXObject(“Microsoft.XMLHTTP”);

 

 

创建XMLHttpRequest对象的函数

 

Function createXMLHttpRequest(){

Try{return new XMLHttpRequest();}catch(e){

         Try{return new ActiveXObject(“Msxml2.XMLHTTP”);}catch(e){

                   Try{return new ActiveXObject(“Microsoft.XMLHTTP”);}catch(e){

         Alert(“哥们,您用的是什么浏览器?”);

         Throw e;

}

}

}

};

 

 

 

 

 

 

 

 

 

第二步(打开与服务器的连接)

*xmlHttp.open();用来打开与服务器的连接,它需要三个参数

>请求方式:get或post

>请求的url:指定服务器端的资源,例如:day23/AServlet

>请求是否为异步,true表示异步,否则同步请求!

*xmlHttp.open(“GET”,”/day23/A”,true);

如果是get请求,可以在url后面追加参数

如果请求方式是post,需要添加一步:xmlHttp.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);

第三步(发送请求)

xmlHttp.send(null);如果不给可能会造成部分浏览器无法发送!

>参数:就是请求体内容!如果get请求,必须是null .即xmlHttp.send(null);

如果是Post请求,

Send(“username=xxx&password=yyy”); 

第四步(得到响应)

xmlHttpRequest对象有一个onreadystatechange时间,它在xmlHttp对象的状态发生改变时被调用。下面介绍一个XMLHttpRequest对象的五个状态。

0:初始化未完成状态,只是创建了该对象,没有调用open()

1:请求已发送,open()方法已经调用,但还没有调用send();

2:请求发送完成,send()方法已经被调用

3:开始读取服务器响应

4:读取服务器响应结束

*得到xmlHttpRequest对象的状态

       Var  state = xmlHttp.readyState;//0 1 2 3 4

*得到http状态码

       xmlHttp.status

*得到服务器响应的内容

       Var  content = xmlHttp.responseText;//得到服务器响应的文本格式内容

       Var  content2 = xmlHttp.responseXML;//得到响应的XML格式的内容,它是document对象了!

 

xmlHttp.onreadystatechange=function()

{

         if(4==oAjax.readyState)

         {

                   //http状态码 200代表成功

                   if(oAjax.status == 200)

                   {

                            alert(oAjax.responseText)

                   }

         }

};

 

 

 

 

 

 

 

 

 

 

 

 

相应内容为XML:

       *服务器端设置相应头:Content-Type,其值为 text/xml;charset=utf-8

       *客户端:

       >var doc = xmlHttp.responseXML;//得到的是Document对象

 

 

 

XStream

 

作用

XStream 可以把 javabean 转换成 XML!

通常服务器向客户端响应的数据都来自数据库的一组对象,而我们不能直接把对象响应给客户端,所以我们需要吧对象转换成XML在响应给客户端,这是就需要使用XStream组合

Jar

核心包是:xstream-1.4.7.jar

必须依赖包:xpp3_min-1.1.4c(XML Pull Parser,一款速度很快的XML解析器)

 

使用步骤

XStream xstream = new XStream();

String xmlStr = xstream.toXmlStr();

细节:

       Day23 XmlDemo详情

*别名:把类型对应的元素名修改

>xs.alias(“china”,List.class);让list类型生成的元素名改成china

*使用为属性,默认类的成员,生成的是元素的子元素,我们希望让类的成员生成元素的属性

>xs.useAttributeFor(Province.class, “name”);把province类的name属性,生成<province>元素的属性

 

*去除collection类型的成名

>xs.addImplicitCollection(Province.class, “cities”);让province类的名为cities的属性集合不生成<cities>,但其内容依然会生成元素

*去除类的指定成员,让其不生成XML元素

>xs.omitField(City.class, “description”);在生成的XML中,不会出现city类,名为description对应的元素

 

JSON

Day23

Json它是js提供的一种数据交换格式

Var person = {“a”:”1”,”b”:”2”,”c”:”3”, “age”:18};

       {}:是对象

       >属性名必须使用双引号括起来!单引号不行

       >属性值:

              *null   数值   字符串  数组:使用[]括起来 

              Boolean值

函数:eval(“(” + str + “)”);   将str当成json解析

 

Json-lib

它可以把javabean 转换成  json串

Jar包:

       核心包:json-lib.jar

       依赖包:commons-lang.jar  commons-beanutils.jar commons-logging.jar

Commons-collections.jar   ezmorph.jar

核心类:

       *JSONObject  ---Map

              >toString();//  json  str

       *JSONArray   ---List

              >toString();//json  str

 

JAVA WEB三大组件

  1. Servlet
  2. Listener
  3. Filter

 

 

Listener

观察者模式:(监听)

  1. Java web  监听器概述

在java web中被监听的事件源为:ServletContext,HttpServletRequest,HttpSession三大域对象

    1. 监听域对象的‘创建’和‘销毁’的监听器
    2. 监听域对象“操作域属性”的监听器
    3. 监听HttpSession的监听器

事件源

1.ServletContext

             *生死监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在销毁时调用

             *属性监听:ServletContextAttributeListener,它有三个方法,分别在添加,修改,移除属性时调用

      2.HttpSession

             *生死监听:HttpSessionListener,它有两个方法,一个在出生时调用,一个在销毁时调用

             *属性监听:HttpSessionAttributeListener,它有三个方法,分别在添加,修改,移除属性时调用

      3.ServletRequest(用户发出请求,请求动态资源)

             **生死监听:ServletRequestListener,它有两个方法,一个在出生时调用,一个在销毁时调用

             *属性监听:ServletRequestAttributeListener,它有三个方法,分别在添加,修改,移除属性时调用

 

 

注意:

感知监听(都与HttpSession 相关)

 

*它 用来添加到JAVA BEAN 上,即javabean实现某个接口

*这两个监听器都不需要在web.xml中注册

HttpSessionBindingListener:添加到javabean上,javabean就知道自己是否添加到session中;

 

HttpSessionActivationListener 由bean实现,bean就知道自己是否被一起序列化和反序列化;

(设置tomcat将一定时间没有活动的session序列化到硬盘上,这样做是节约内存。当用户继续访问时,再从硬盘式反序列化会内存,默认是不会这么做的)

(tomcat在关闭前,会把session序列化到硬盘上,如果session中包含了可序列化的值,则该值一起随session序列化;如果该对象没有序列化,则被session抛弃;

Tomcat开启后,会反序列化所有session;‘复活’)

Session序列化:

钝化session对象,就是把session通过序列化保存到硬盘文件上;

当用户再次使用session时,tomcat会把钝化的session在活化,所谓活化就是通过反序列化的方式将文件中的session读回内存中;

详情在day20 .doxc 中

 

 

编写一个Listener

  1. 写一个类实现某个监听接口

 

2.配置web.xml  

      <listener>

             <listener-class>cn.itcast.web.listener.AListener</listener-class>

      </listener>

 

 

过滤器Filter

      它会在一组资源(jsp,Servlet, .css, .html)的前面执行!

      它可以让请求达到目标资源,也可以不让请求达到!

      *它有拦截请求的能力

 

 

 

 

过滤器编写

  1. 写一个类,实现Filter接口
  2. Web.xml中配置

<filter>

       <filter-name>xxx</filter-name>

<filter-class>com.web.filter.AFilter</filter-class>

</filter>

<filter-mapping>

       <filter-name>xxx</filter-name>

       <url-pattern>/*</url-pattern>

</filter-mapping>

 

 

Void init(FIlterConfig)创建后执行

Void destroy()销毁之前执行

Void doFilter(ServletRequest ,ServletResponse,FilterChain)

每次过滤时候都会执行

 

FilterConfig和ServletConfig对象相象

*获取初始化参数:getInitParameter();

*获取过滤器名称:getFilterName();

*获取application:getServletContext();

 

FilterChain

       *doFilter(request,response)放行!!!

 

多个过滤器的执行顺序

FilterChain#doFilter()

       执行目标资源,或者执行下一过滤器

       如果没有下一个过滤器,执行目标资源

       如果有,执行下一个过滤器

例子:A  ---黑风山  --- 清风寨  ---- b  --   清风寨 --- 黑风山----- A

如果使用Web.xml文件

Filter-Mapping的配置顺序决定了Filter的执行顺序

 

如果使用@WebFilter注解,当使用注解配置多个Filter时,用户无法控制其执行顺序,

此时Filter过滤的顺序是按照Filter的类名来控制的,按自然排序

过滤器的四种拦截方式

       *拦截请求   request

       *拦截转发    forward

       *拦截包含    include

*拦截错误    error

 

在Filter-Mapping 中进行配置

<dispatcher>request</dispatcher>

默认是request,

 

WebFilter注解:实例

       @WebFilter(urlPatterns={“/*”},dispatcherTpes={DispatcherType.FORWARD})

 

 

servlet 3.0

异步处理

什么是异步处理,原来,在服务器没有结束响应之前,浏览器是看不到响应内容的,

只有响应结束,响应的内容才会显示出来。现在异步处理的作用:在服务器开始响应后,

浏览器马上看到相应内容,不用等待服务器响应结束.

 

实现异步的步骤

*得到AsyncContext ,它异步上下文对象

       > AsyncContext   ac   =  request.startAsync(request, response);

       >给异步上下文ac  一个Runable对象,然后启动!(给上下文一个任务,然后完成)

       _ac.start(new Runnable(){

       Public void run(){…}

});

*webServlet(urlPatterns=””, asyncSupported=true)

*response.setContentType(“text/html;charset=utf-8”);如果没有编码,可能异步失败

*IE如果不能正常异步输出,说明响应体大小不足512B, 需要多输出点东西

*ac.complete();通知tomcat我们的异步线程已经结束,让客户端不再等待

 

3.0对上传的支持

默认servlet不支持上传组件,需要提供注解

       @MultipartConfig

*表单不变

*在处理的servlet中,不需要再使用commons-fileupload

而是使用servlet 3.0 提供的上传组件的接口

接口:Javax.servlet.http.Part  :表示一个上传的文件

而如何得到part?使用request中的getPart(“字段名”);方法

类:

ThreadLocal    副本,线程并发

 

MessageFormat :   模板 :“12{0}bc{1}“ “1”, “2”   参数代替掉模板中的占位符

BigInteger:  处理大的数

BigDecimal

    * 可以处理二进制运算的误差

   *BigDecimal构造必须使用string的构造器

Timestamp   对应数据库表的  datatime

 

 

在抽取service的接口时候,如果有一个基础的通过id的查询方法

可以这样声明:Object findById(class clazz, java.io.Serializable id);

使用时:findById(User.class, 2);//ok

因为大多数类都实现了Serializable接口

 

 

 

总结

  1. 如果一个类的某个非主属性是另一个类的主键,或一对多  Order 包含了许多orderItem等包含关系,类中必须使用引用而不能使用基本属性.方便后面的开发
  2. DAO层中如果有异常,最好抛出RuntimeException,方便Service层得到异常
  3. Service层要验证数据的安全性,抛出异常给Servlet层;数据验证可以在service层处理
  4. sql service 数据库的sql语句在QueryRunner中使用必须 注意表名和( 之间的空格

 

 

问题

无法跳转到Jsp页面的问题:(jsp文件和访问路径都没问题) 文件名前面有一个空格

QueryRunner 对datetime的支持不好,当datetime类型的字段为null,会报错

猜你喜欢

转载自blog.csdn.net/JIANG_RZJ/article/details/82591580