Javaweb学习笔记



day08 14
http协议   请求协议....响应协议......
响应行状态码:
 以2开头,成功
 以3开头,要转接
 以4开头,客户端的错   404,访问了不存在的东西
 以5开头,服务器的错   500,服务器代码异常


字符编码问题...
utf编码,表单数据提交使用的编码




day08 16
referer请求头(重要):统计访问量、防盗链
Tomcat把动态资源变成静态资源发送给浏览器,浏览器才能看懂
html页面中meta标签可以模拟响应头,注意不能模拟请求头


day08 18
设计验证码图片




day09
主要讲servlet的基本知识


day09 4
注意servlet会有线程安全问题(不是线程安全的)


day09 5
servlet是单例的,一个类就对应一个对象,当然不同类会有不同对象


day09 6
ServletConfig是个接口(今后遇到的很多都是接口!!!)
我们并没有写它的实现类,是因为tomcat帮我们提供了实现类(之前的AServlet是Servlet的实现类,是
我们自己写的,但是ServletConfig的实现类自己没有写,由Tomcat帮我们提供)


ServletConfig四个方法中,其实真正有用的是getServletContext(), 返回值ServletContext




day09 8
带参数的init方法才是真正的生命周期方法!!!!!
在GenericServlet的实现中,我们定义了一个空的init()方法,把它放在有参的init()方法中,
这样,在我们写一个Servlet类继承GenericServlet时,可以通过重写无参init()方式实现出生时要


GenericServlet实现了ServletConfig接口,ServletConfig能完成的内容它都能完成。


day09 9
错误码405:不支持这种请求方式。注意doGet和doPost方法本身不是抽象的,默认的实现是给
客户端一个405状态码。所有我们常常要重写这两个方法,这样就不会出现405了。
另外HttpServlet是抽象类,但是没有任何的抽象方法,说明你不能直接用我,你还得继承我。


创建Servlet类时,可以直接new-Servlet,这样web.xml自动帮我们配好了。不过自带的
Servlet模板比较烦,很多不需要的东西。


day09 12
Servlet与反射:在web.xml配置文件中通过url-pattern找到servlet-class字符串后,肯定要用反射
来创建Servlet对象(需要一个无参构造器)。
反射运用还是很广的,特别是谈到和配置文件相关的东西。重在理解,我们一般不需要写反射代码。


day09 13
一个项目只有一个ServletContext对象!!!常常给他取名application,把多个Servlet串起来
与天地同寿!服务器启动时创建,服务器关闭时死去!


day09 17
我觉得奇怪的是,getRealPath()不管输入什么字符串都行。。


day09 18
练习:统计网站访问量(在项目day09_3里面)
注意向浏览器输出使用到了response对象和PrintWriter流


day09 19
一个web项目,所有src下的东西都会在WEB-INF---classes出现
src下的东西将来不会发布给用户,只会发布WebRoot,所以src下的.java
会出现在WEB-INF中变成.class,而其他文件会原封不动地copy进来。


个人理解:要获取web根目录的资源(即WebRoot文件夹下的东西),用
          17节讲的知识(即用ServletContext)比较
 要获取类路径下的资源(ClassLoader用的多,统一不带斜线,而用Class还有
 带和不带两种),用19节讲的知识。
 即一个是ClassLoader的getResourceAsStream方法,
   一个是ServletContext的getResourceAsStream方法
 详见day09_2里面的DServlet和EServlet!!!!
另外EServlet还用到了方便操作流的类库,IOUtils。常用的工具类已下载。




day10
主要讲response,request


day10 1
MyEclipse的配置是基于工作空间的,换了工作空间以前的配置就没用了,
还得重新配置。


day10 2
request response对象是服务器创建的,浏览器一辈子和对象无缘
浏览器只能发送http请求,接收http响应。
request response生命短,请求结束就死了,有新的请求又创建新的request response。


day10 4
响应头,就是键值对!!注意可能存在一个名称对应多个值!!(比较少)
最重要的一个设置响应头方法setHeader():适用于单值的响应头
    例如,response.setHeader("aaa","AAA");
response.setDataHeader("expires",1000*60*60*24);设置页面过期时间为一天
    一般初学阶段设置为-1,即不让它缓存


day10 5  重定向
记住所有的重定向都要带上Location头!!!
响应头大小写都行,但一般首字母大写
重定向:response.setHeader("Location","/day10_1/CServlet");
    其中,/day10_1/CServlet叫 请求URI (url与uri区别??)
          /day10_1叫          项目名
 /CServlet叫         Servlet路径(就是web.xml里面的url-pattern)
更清楚地理解重定向,可以使用chrome浏览器,开发者工具。


day10 6  定时刷新
能完成重定向、定时刷新等功能是因为浏览器能看懂这些头,
我们瞎写一个头那肯定不行。
乱码初体验...........
注意:重定向和定时刷新很相似,一个是立即,一个是过一段时间。


day10 7 禁用浏览器缓存
三管齐下:Cache-Control、pragma、expires
记不住这三个名字咋办,打开index.jsp,里面meta可以充当响应头。


day10 8 response响应体
getOutputStream和getWriter是互斥的,只能用其中一个!!!
同时用会抛IllegalStateException异常


字节流万能的,可以将字符串转化为字节数组(getBytes方法),再用getOutputStream
字符流不是万能的
响应体通常是html,也可以是图片
响应图片:day10_1/GServlet


day10 9
快速重定向:sendRedirect(String location) 方法


day10 10  request
获取常用信息:
    获取客户端IP,request.getRemoteAddr()
    获取请求方法,request.getMethod(),可能是POST或GET
    注意:一般从地址栏输入或点超链接都是GET请求,提交表单我们设置为POST请求
          时才是POST请求
获取HTTP请求头:
    ***最重要的方法,String getHeader(String name),适用于单值头
    Enumeration其实是老版本的迭代器
User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
5.1 XP
6.0 Vista
6.1 win7


day10 11 获取请求URL
一个完整的请求URL:
    http://localhost:8080/day10_2/AServlet?username=xxx&password=yyy
有相应的方法获取里面的各部分内容,详见day10_2/CServlet


day10 12  防盗链
利用referer请求头!!详见day10_2 BServlet


day10 13  获取请求参数
无论是GET还是POST,获取请求参数方式都相同
比较重要的两个方法:
    ***String[] getParameter(String name);获取指定名称的请求参数值,适用于单值请求参数
    ***Map<String,String[]> getParameterMap();获取所有请求参数,可处理多值


想对ArrayList等输出,直接syso就行,因为重写了toString方法
想对数组输出,用Arrays.toString()方法


*****这个知识点比较重要!!!以后会经常遇到获取参数的例子,比如登录等等。
     详见/day10_3/AServlet  其中发现一个问题,使用HTML5会产生乱码,HTML4不会,兼容问题?


day10 14  请求转发和请求包含(有点不好理解)
一个请求链中涉及到多个Servlet!!但总共就一个请求!!和重定向不同,重定向
实际上包含了两个请求。
这样理解:在客户端不知情的情况下,一个Servlet找另外的Servlet帮忙。因为总共
          一个请求,所以Tomcat总共创建了一个request、一个response,大家的
 Servlet都是相同的,因此可以在多个Servlet间共享数据,称之为request域。
 javaweb,或者说Servlet中有三大域,这是第一个。
request和response经常是成对出现,需要一个作参数,往往也需要另一个。


***********response既能getHeader又能setHeader!!


请求转发(***):当前Servlet只能设置响应头(留头不留体),下一个Servlet又能设置头又能完成响应体。
                 别人找他帮忙,当然他比较牛逼。
请求包含:共同协作(都留)
***详见/day10_3/OneServlet和/day10_3/TwoServlet


注意一个重名的问题:
    ***在另一个包(比如servlet.include)中也可以有类名为OneServlet、TwoServlet的Servlet,但是,
    Servlet名不能再是OneServlet、TwoServlet,最好加个前缀改成IncludeOneServlet、IncludeTwoServlet
    因为web.xml配置文件中Servlet名不能重复!!!!


day10 16
Servlet中三大域对象:request、session、application,都有如下三个方法:
    void setAttribute(String name, Object value)
    Object getAttribute(String name)
    void removeAttribute(String name)  一般对后面两个域对象用,因为他们命长,属性总留着占内存
同一请求范围内使用request.setAttribute()、request.getAttribute()来传值!!
对于重定向,第二个Servlet拿不到第一个Servlet设置的属性,因为是两个请求,第一个请求结束时
会杀死第一个request。而请求转发的话可以!!因为就是一个请求!!


注意,别把这里的属性和13节讲的参数搞混!!那里的参数是客户端发给服务器的。一提到request域,就是
    一个范围包含了和属性(Attribute)相关的方法,和参数无关!!!


day10 17  乱码问题!!!!
响应编码...请求编码...
详见/day10_4/AServlet


day10 20 URL编码
它不是字符编码!!
表单会自动转,如果是一个链接中有中文参数需要我们自己转(用到后面JSP知识...)


day10 21 路径问题
感觉路径问题非常烦!!
ClassLoader获取资源时不能以“/”开头!
Class获取资源时不加“/”表示.class文件所在目录   加“/”表示classes文件夹下的目录,即与ClassLoader相同




day11 2  JSP基础
JSP其实就是一个Servlet,一个化了浓妆的Servlet。
JSP是服务员(作为请求发起页面和结束页面),Servlet是厨师(处理数据)
JSP包括html、java脚本(三种)、jsp标签(指令)
视频中提到的知识:
class MyClass{
成员
方法
构造器
构造代码块
静态块
内部类
}
关于java类中的非静态代码块和静态代码块 https://zhidao.baidu.com/question/393900964.html


day11 3
演示三种脚本怎么写。注意有些东西只学不用,实际中不会这么写


day11 4
讲Jsp和Servlet分工的案例(一个JSP中表单提交两个数,Servlet求和,在另一个Jsp页面中显示)
详见/day11_1/jia 文件夹
引发的问题:
  Object obj = new Integer(100);
  String strVal = (String)obj;
  编译通过,运行出错


day11 5 JSP原理
注意看几个截图,JSP页面内容是怎么和翻译的.class内容对应的
JSP真身在Tomcat的work目录下!!


day11 6 注释
<%==   ==%>  直接被忽略
<!--   -->   这是html注释,浏览器能看见只是不显示


day11 7 Cookie入门
Cookie是不能跨浏览器的!!!
保存和获取Cookie:详见/day11_2/cookie1 文件夹


day11 8 cookie生命
详见/day11_2/cookie2 文件夹


day11 9 cookie的路径
cookie的路径不是设置这个cookie在客户端的保存路径!!!
浏览器访问服务器的路径,如果包含某个cookie的路径,那么就会归还这个cookie


day11 11 HttpSession入门
一个用户不可以同时拥有两个Session。打开两个浏览器算两个用户!!!
**********Cookie和Session:
Cookie保存在客户端,而Session是服务端对象,保存在服务端!!
Cookie和Http协议有关(有对应的请求头和响应头),而Session和Http协议无关。


day11 14 *****登录案例****
很重要的案例!!!详见/day11_3/session2文件夹
出现的问题:当用户名为中文时,保存cookie会出错,是需要URL编码么??


day11 15  HttpSession原理
貌似是我们一关浏览器,服务器就把session杀死。其实不是!!服务器根本不知道我们关了浏览器,
只是我们关闭浏览器时丢失了sessionID,新开浏览器又是新的sessionID(它对应一个cookie,生命设为-1)
因此,之前的session没人用了,过了一段时间(默认30分钟)服务器就把它抛弃了。
联想到日常经历:逛淘宝,登录以后,盯着一个页面看了很久,终于决定下单时又要重新登录...


使用JSP时,就已经创建session(内置对象),也有sessionId这个cookie。但是使用Servlet时就不一样了,
如果没有使用request.getSession()这个方法,就没有创建session,也没有sessionId。


day11 16
第一次自己写工具类:生成32位的随机十六进制字符串,以后还会经常写工具类。
位置:/day11_3/commons/CommonUtils


HttpSession其他方法:
有一个比较重要的方法:void invalidate()  让session失效,客户端再次请求创建新的session
比如:登录淘宝后,页面上有个“退出”按钮,用的就是这个方法


day11 17  url重写
浏览器禁用了cookie怎么办,把cookie用请求参数来替代!




day12 1  
设计验证码图片****  /day11_3/image/VerifyCode


day12 2
在day11 14的登录案例中加入了验证码!!!
“看不清?换一张” 功能中,用到了JavaScript知识,每次请求VerifyCodeServlet换一张图,而不用
刷新页面。为了解决因浏览器缓存不换图的情况,每次设置src时加了一个总是变化的参数,骗浏览器用。




day12 4 page指令
JSP中三大指令:page、include、taglib,page最常用也最复杂
一个jsp页面中,可以有0~N个指令的定义!


任何异常出现,错误码都是500!!!
web.xml中配置错误页面 


九大内置对象中,只有session和exception可能不能用:
**若当前页面session属性设置为false,则不能用session对象(基本没人这么干)
**当前页面isErrorPage属性设置为true时,才能用exception对象
其他内置对象肯定能有!!!


day12 5
pageContext一个顶九个!!!
注意page域指的就是pageContext的作用范围,和那个page内置对象(这个对象没啥用)没关系。


day12 6  另外两个指令 include和taglib
include是静态包含!!是在JSP编译成Java文件时完成的(大前期...)。因此不能包含一个变量名,因为
这个时候还不认识这个变量。
taglib:导入标签库
两个属性 prefix 、uri


day12 7  jsp动作标签
JSP2.0 20个动作标签,但大多没用。动作标签是由服务器解释执行,和HTML标签有本质区别。
标签前缀是固定的:jsp
包含有静态包含动态包含一说,转发没有。注意静态包含和动态包含的区别!!!


day12 8  关于一些配置的东西
在conf/context.xml中,可以在Context后这样配置,reloadable="true",这样不用总重启Tomcat。
但是这样做仅仅适用于项目开发阶段,而且有弊端。


day12 9  JavaBean
JavaBean的规范:
1、必须有默认构造器
2、提供get/set方法,如果只有get方法,那么这个属性是只读属性!
3、属性:有get/set方法的成员,还可以没有成员,只有get/set方法,属性名称由get/set方法来决定!
4、方法名称满足一定规范,那么它就是属性!boolean类型的属性,它的读方法可以是
  is开头,也可以是get开头。


内省:
   内省类--> Bean信息 --> 属性描述符 --> 属性的get/set对应的Method --> 可以反射了!
   commons-beanutils 它是依赖内省完成,而内省又依赖反射!
   * 导包
> commons-beanutils.jar
> commons-logging.jar


BeanUtils的使用*****
    详见/day12_2/domain 包
    以后可以一句话将表单数据封装到JavaBean中!!!
即用request.getParameterMap得到一个map,再将map转换到JavaBean中
    因为以后表单数据可能很多,所以这样做很有效率!


day12 11  jsp中与JavaBean相关的标签
现在已经没人这么用了,这还是model1年代(不用Servlet,全是jsp)的做法。今天这种东西都在servlet中用。




day12 12 EL入门


JavaBean导航很重要,.加属性名等于调用get...方法




day12 13  11个内置对象
11个内置对象,10个是Map!!
*****以后项目名用 pageContext.request.contextPath 代替,这样客户改项目名也不怕了
EL表达式中session不是内置对象,不能直接用。但是有一个厉害的pageContext,它一个顶九个
即可以这么用:${pageContext.session.id}   获取JSESSIONID
详见/day12_3/WebRoot下的一系列文件夹


day12 14 EL函数库
都是一些字符串操作的函数




day13 2 JSTL概述
Apache的东西,依赖EL
四大库:core  核心库,重点
fmt  格式化:日期、数字
后面两个过时了


使用out标签可以防止JavaScript攻击,因为out标签里面默认escapeXML=“true”
out标签里面value后面跟的值必须加引号(里面可以写${...}),不能直接写变量


remove 删除域变量,注意默认是删除所有域


day13 4 url标签(重要)
* value:指定一个路径!它会在路径前面自动添加项目名
<c:url value="/index.jsp"/> 输出/day13_1/index.jsp
* 子标签:<c:param>,给url后面添加参数,
<c:url value="/index.jsp">
  <c:param name="username" value="张三"/>
</c:url>
输出为:/day13_1/index.jsp?username=%ED%2C%3F%ED%2C%3F
*var: 指定变量名,一旦添加了这个属性,url不输出到页面,而是保存到域中


以后需要写项目名有两种方法:
   *  ${pageContext.request.contextPath}/index.jsp   不用导库
   *  <c:url value="/index.jsp"/>  需要导库


day13 5 
if标签 相当于if语句
choose标签 相当于if..else if...


day13 6 forEach
可实现for foreach 的功能


***发现的问题:Java脚本里面设置的变量只有脚本里面能用,不能直接${...}输出
      只有将变量设置到域中,才能在脚本外使用!!
***注意的问题:表现属性不要多写空格!!否则错误很难查出


day13 8 fmt标签
<fmt:formatDate value="" parttern="yyyy-MM-dd HH:mm:ss"/>


<fmt:formatNumber value="" pattern="0.00"/>不足的话补位,四舍五入
<fmt:formatNumber value="" pattern="#.##"/>不足的话不补位,四舍五入


day13 9 自定义标签
jsp2.0以后尽量不要用Java脚本。向域中设置参数可以用Servlet,再转发到jsp页面,然后jsp页面取数据就行,
可以用${}取数据。视频中写Java脚本是为了演示方便。


视频中导库写的是  uri="/WEB-INF/tlds/itcast-tag.tld"
        我写的是  uri="http://www.nankai.cn/tags/1.0" 直接Alt+/找到的
貌似这两种方法都行。


实际中,不用实现SimpleTag接口来完成标签处理类,而是继承SimpleTagSupport类,它已经实现了该接口
就好比写Servlet我们也不是直接实现接口,而是继承HttpServlet类。


day13 13 MVC
不是Java独有的!
几乎是所有的web(B-S)都使用MVC!!!


M -- model 模型(直接写代码)
V -- view 视图(jsp)
C -- Controller 控制器(Servlet)


JavaWeb三层框架:


Web层 -- 与web相关内容(Servlet、JSP、request、response)
业务层 -- 业务对象(Service)  request、response等不能出现在这!!
数据层 -- 操作数据库(DAO  即Data Access Object) 所有对数据库的操作不能跳出到DAO之外!!


day13 15 
演示三层框架




day14 2
cn.itcast.web.servlet为什么还加个web,因为servlet是Javaweb三大组件之一,以后可能还加别的。
要学会看包名:
    一般从第三段或第四段开始看(前面是公司名倒写),依次是项目名、模块名等。


day14 3
***导入jar包
***改Servlet模板


day14 4
不要污染Service!!!


day14 6~8 Dao层实现
注意:这里Dom4j的回写操作与我之前学的不一样,主要有两点:
1,设置OutputFormat,我直接用的“漂亮格式”,这里的更复杂一些
2,回写文件我用的FileOutputStream即字节流,这里说用字符流更好,并且设置了编码(更复杂)。
  测试发现我的方法也行,没有乱码。


day14 13 加验证码
可以参照之前学的
注意一个问题:如果是IE浏览器,在js中通过id获取元素,如果另一个元素的name属性
也叫这个名字,则可能获取不到那个元素。(尽量别重名就行)


day14 12 表单校验
发现的问题:
    EL表达式中可以直接写map.key的形式,比如视频中的${errors.username}
    这应该不算JavaBean导航吧,算是EL表达式 的方便之处??
    话说回来,EL的11个内置对象中10个是map,所以这也能说得通。


以后写Servlet,常常第一件事就是封装表单(或超链接参数)!!


day14 14 登录
以后玩登录,一登录成功,就将用户数据保存到session域中!!
注意为了不让硬闯,得先判断session中是否有用户,没有的话打回到登录页面。




day15 1 MySQL
我们常说的数据库指 RDBMS 关系型数据库管理系统


day15 2
可能数据库服务器和应用程序相隔很远!!


day15 4 删除MySQL
挺重要的!!要删干净不容易,包括一些注册表!!


day15 5
mysqld.exe 查查任务管理器中有没有,这是MySQL的服务器端程序,必须要有!
mysql.exe 这是客户端程序,用来连接服务器,可以开启多个


day15 7
SQL语言虽然是标准化语言,但每个数据库都有自己的一些方言。
比如MySQL里面的limit,Oracle看不懂。


day15 8
方括号里面表示可选的,自己写的话别加方括号。


day15 9
char与varchar:各有优缺点,varchar需要单独拿一个字节来记录长度。
关于varchar长度到底是字节还是字符:
    貌似没有统一的答案。据说,4.0以下指字节,5.0以上指字符。
text是mysql独有的(官方是clob)
tinytext -- text -- mediumtext(16M多) -- longtext(4G)   超大文本


day15 12
字符串用单引号!!
发现的问题:
    插入数据时,若是一个字符串,里面的空格都算。但是,如果该列数据类型是char,
    而插入的字符串超出了,则会自动去掉末尾空格。仍然超出则报错。


day15 13
出现了 =null ,那就是false,要判断是不是null,应该用 is null。


day15 16
注意 + 并不能连接字符串,用concat('','')连接。oracle中俩竖线。
select concat('我叫',name,',我的工作是',job) from emp;
怎么处理Null   select sal+ifnull(comm,0) from emp;
起别名  as可以省略


day15 18 模糊查询
使用关键字like   _ 一个字符
        % 0个或多个字符


day15 19
排序时,可以加多个指标,若第一个指标相同,则按第二个指标排序。
如:select * from emp order by sal asc, comm desc, empno asc;


day15 20
count(1),count(200)等等和count(*)效果一样,但没人这么用,就拍别人考。


day15 20 简单聚合函数
select count(*) 人数,sum(sal) 总和,max(sal) 最高,min(sal) 最低,avg(sal) 平均 from emp;


day15 21 分组查询
****************
在分组情况下,select 后只能跟组信息,包括两个,一是分组列,二是聚合函数。
如:select job,count(*) from emp group by job;
job是分组列(与后面的job对应),count是聚合函数,不能select name 。
一般养成习惯分组的话select后面先写分组列!!


select
from
where      分组前条件,没参与分组 (即分组前先把一部分干掉)
group by
having     分组后条件(经常是聚合函数)
order by




day16 2 编码问题(只针对小黑屏)


注意:Mysql其他内容是回家一段时间看的,这里没有笔记,截图也没有!!!后面直接进入JDBC。




day17 JDBC
背下来:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mydb1


com.mysql.jdbc.Driver这个驱动类是MySQL提供的,若变成了oracle,这个驱动类肯定要变。即各个数据库
厂商都提供了属于自己的驱动类,为了实现JDBC规范(其实是一组接口)。同理url也得跟着数据库而变。


Class.forname(...)加载驱动类。不写这个将找不到驱动。
注:新版本的驱动包不写这个也行,但最好还是写上吧。


四大参数!!!


JDBC协议格式!jdbc:厂商名称:子协议(由厂商自己规定)
对mysql而言,子协议结构://主机:端口号/数据库名称


JDBC一般对记录进行操作,很少对表结构进行操作!!


day17 3 实现增删改查
别忘了最后将资源关闭!! rs、stmt、con


day17 4 代码规范化
循环遍历rs时,若搞不清列的数据类型,用getString或getObject是通用的。


day17 5 滚动结果集
用得少 就next()用得多!


con.createStatement()  默认是不滚动,不敏感,不可更新!但是,MySQL默认是滚动的!


day17 7 
SQL攻击,输入的用户名为SQL语句的片段,造成'a'='a'永远为真。
PreparedStatement的作用之一就是防止SQL攻击。


day17 10 JdbcUtils 1.0
这一节很难!!
用到了Properties类,配置文件,实际上是键值对。
用到了获取类路径下资源方法 JdbcUtils.class.getClassLoder().getResourceAsStream("...");
用到了static静态代码块。


day17 11 面向接口编程
思想很重要!!!
  把UserDao修改为接口,并提供实现类,但是不是直接用实现类,而是通过工厂(DaoFactory)取实现类,
怎么取的?工厂通过配置文件(.properties)获取实现类的类名,再用反射得到实例,返回即可。
  这样做的好处:最大程度解耦,全篇代码没有出现实现类的名字,若实现类变了,用户只需改配置文件,
而不用修改程序。


day17 12 day14DAO层的修改
代码见day14的代码。
JDBC连接数据库!!只需要写一个新的实现类即可,实现UserDao接口!!然后把配置文件改了,其他不用变!
里面用到了通过ClassLoader获取资源(获取的是个配置文件),并把相应代码放到static代码块中,最近常常用这个套路。
里面用到了ORM,对象关系映射,后期复杂的时候得用hibernate。


day17 13  时间类型转换
java.sql包下的东西绝对不能出现在DAO以外的地方!!
原则就是每一层只管自己这一层的东西,不要泄露给别的层。
另外,领域对象(domain)中的所有属性不能出现java.sql包下的东西!即不能使用java.sql.Date
这节考虑java.sql.Date和java.util.Date的转换问题


day17 14 大数据
把一首MP3放入数据库,然后读取出来放到磁盘上。
详见day17_1/...demo4
存MP3可用mediumblob类型。
需要在my.ini修改 max_allowed_packet,不然MySQL不让放这么大的数据。
IOUtils的使用!!!
IOUtils.toByteArray (输入流转换为字节数组)、IOUtils.copy (可以将输入流数据写入到输出流)


day17 15 批处理
详见day17_1/...demo5
pstmt.addBatch();
pstmt.executeBatch();
注意,很多人认为MySQL不能提供批处理,这是不对的!MySQL默认把批处理关闭了,需要在url后
      配置参数 rewriteBatchedStatements=true。这样就能快很多!
另外,给程序计时:
    long start = System.currentTimeMillis();
    long end = System.currentTimeMillis();
    syso(end-start);




day18 01 
事务的四大特性(ACID),背下来!


day18 3
JDBC中处理事务,通过con完成。
记住,同一事务中所有的操作,都要使用同一个Connection对象!!!
这里写的是不完善的业务层(被JDBC的东西感染了),后面会解决(也不知道啥时候)。


day18 4 事务的隔离级别
并发读问题:
    脏读(严重)
    不可重复读
    虚读
四大隔离级别:mysql用的是repeatable read(可重复读),Oracle用的是read committed(读已提交)


day18 5 数据库连接池
常量池、线程池、连接池。。
需要导入三个jar包,那个我们自己写的小工具类JdbcUtils就不用了,因为我们是用连接池创建连接,作用一样。
javax.sql 包下有一个DataSource接口,任何实现了它的类就是数据库连接池!!
我们用的连接池一般都是实现了这个接口的、第三方提供的连接池。
一般一个项目一个连接池就够了。


装饰者模式
*连接池内部使用四大参数创建了连接对象!即MySQL驱动提供的Connection
*连接池对Connection对象进行了装饰,只对close方法进行了增强
*装饰之后的Connection的close方法用来把当前连接归还给池! 



day18 6   *****装饰者模式*****
在IO流中有大量使用!!


***对象增强手段:
       *继承
       *装饰者模式
       *动态代理 (更加高级,AOP面向切面编程)


***是你还有你,一切拜托你!!!


装饰模式简单实例:给文件加密,见截图。


day18 7 c3p0连接池
据说它的作者是星球大战迷,c3p0是其中一个机器人名字。
它四大参数的配置 方法名字和dbcp有三个不一样...只有一个setPassword是一样的。
***C3P0底层用的动态代理,用System.out.println(con.getClass().getName());输出类名就清楚了
   com.mchange.v2.c3p0.impl.NewProxyConnection   proxy是代理的意思


day18 8 c3p0 配置文件
默认配置、命名配置
day18_3 demo1  配置文件中只写了默认配置


day18 9 JdbcUtils第二次更新


day18 10 JNDI配置
Catalina/locahhost 下创建 day18_4.xml,在这里给出<Context>...</Context>,只对该项目有效
可参考 配置外部应用一节!!
JNDI配置好后,就是获取资源。获取资源的代码背下来就得了!
详见day18_4/AServlet 获取资源。


注:现在不太明白的是为什么要通过JNDI的方式来获取(感觉还麻烦一些),像之前那样直接获取貌似方便一些。
还有一点,若Tomcat下没有了那个项目(如day18_4),那么必须把day18_4.xml移除,不然出异常。




day18 11 ThreadLocal
其实不想共享数据,只想每个线程有自己的副本。
通常用在一个类的成员上,每个线程有自己的副本互不干扰,解决并发访问问题。
内部实现是个Map,使用当前线程(Thread.currentThread)作为key!!
这节涉及到的知识:多线程,通过匿名内部类方式创建多线程,不熟悉的话看以前知识和截图。
见视频day18_5 工程,这个我自己没写。


day18 12 dbUtils
将数据库的操作进一步简化。
详见day18_5  该节内容其实很多,建议再看视频!


day19 13 dbutils结果集处理器介绍
5个结果集处理器要记住!!2个转换为JavaBean,2个转换为Map,1个处理单行单列!
视频中分别进行了演示,我没写。




day19 1、2  BaseServlet
可以在Servlet中根据传过来的参数调用相应的方法(用反射)。
为了进一步简化转发和重定向,以字符串形式返回相应的操作。在Baseservlet中对字符串进行处理,
完成相应的操作。
详见day19_1 servlet包


day19 3  JdbcUtils的第三次修改
再次强调:开启事务,提交事务,回滚事务要用同一个连接!!!DAO层相应的连接也得是这个!!
两难问题:
    DAO层不能出现事务!
    Service层不能出现Connection!
解决:
把JdbcUtils修改为DAO层和Service层的中介!增加三个方法:开启事务、提交事务、回滚事务。


day19 4 TxQueryRunner
/**
 * 这个类中的方法,自己处理连接问题,无需外界传递
 * 怎么处理呢
 *     通过JdbcUtils.getConnection得到连接
 *     可能是事务连接也可能是普通连接
 *     由JdbcUtils.release方法释放连接
 *     释放连接包括两个方面,事务连接不关闭,普通连接关闭
 * @author huli
 *


day19 5 JdbcUtils处理多线程并发访问
就是把成员 Connection改为 ThreadLocal<Connection>类型 ,每个线程有自己的Connection




day19 7 
简单的客户关系管理系统
前端知识要补!!!  frame、target、base的作用,jQuery


day19 8
总结小经验:一般都是jsp带着某些参数给servlet,处理完后把结果放到域中转发给jsp。


day19 9  *******
<label></label>标签作用之一:
<input type="radio" name="gender" value="男" id="male"/>
<label for="male">男</label>
for属性的值要和上面标签的id值一致,这样可以将label的内容赋给input的value。
效果:并不一定非得点中那个小圈圈才能选中“男”,直接点“男”这个字就能选中!!


表单里面想加个参数咋办?
由于是post方式,不要用?后面加参数
可以直接在表单里面写个input加参数,为了防止用户看见,设置type=“hidden” ,视频叫隐藏字段。


day19 12 多条件组合查询
有技巧!!!
SQL利用StringBuilder追加,params利用ArrayList追加
SQL语句里面写 where 1=1 可以省很多事!


day20 分页处理
项目day20_0 是先复制了day19_3 ,然后加上分页处理。
注意复制项目后右键项目,选最后一项,改context Root


分页处理中一个难点,在高级搜索中如何保留查询条件!!
获取URL时注意把表单改成get方式,不然参数获取不到。(post方式参数不在URL里面)
对get请求注意编码处理问题,先退再编。




day20 8 监听器
事件源:三大域:
    ServletContext、HttpSession、ServletRequest
生命周期监听、属性监听


用得比较多的:
对于ServletContext的“出生监听”,可以在这个监听器存放一些服务器一启动就要完成的代码!!


day20 11 session的序列化
session有死而复生的能力!!!
当服务器断开时,在Tomcat的work目录下存有SESSIONS.ser文件(保存到了硬盘上),保存有session。服务器又启动时会将这个
文件读回去。这样,项目上线后,若需重启服务器,用户也不用下线。
注意:在Tomcat的 context.xml文件中配置 <Manager pathname=""/> 可使这一功能作废。


day20 12 session的钝化和活化
在服务器没有断开的情况下,你一段时间(如一分钟)没有动作,则把session从内存中移到硬盘中(钝化)
若有活动了,则又加载到内存中(活化)。期间用户感觉不到。
如何进行配置见视频中。
一个类除了实现HttpSessionActivationListener接口外,还得实现serializable接口,才能陪session一起
钝化到硬盘,然后活化回来。




day21 2 过滤器
过滤器通常用来过滤一批资源,很少说只针对某个servlet过滤。
Filter接口的doFilter()方法,三个参数;
FilterChain的doFilter()方法,两个参数(用于放行)。注意区分。
多过滤器情况下,放行表示执行下一个过滤器,若没有了过滤器,则执行目标资源。这就是“链”。
如果被前一个拦截了没有放行,那就不会执行下一个了。
另外,多过滤器执行顺序是按配置中mapping的顺序。


day21 5
还可以在mapping中指定一个或多个servlet名字来过滤!!说明我就要针对你!!


day21 6 统计访问量
获取IP:request.getRemoteAddr();
可以把IP和对应的访问量放在一个map中,而在ServletContext监听器中完成map的创建,在过滤器完成map修改。
LinkedHashMap


day21 7 权限管理
由ServletRequest request得到session要强转!
给/WebRoot/users下的文件设置保安(filter):url应写  /users/* ,filter中得到session中用户,
设置成会员和管理员才能访问。
给/WebRoot/admin下的文件设置保安(filter):url应写  /admin/* ,filter中得到session中用户,
设置成只有管理员才能访问。
这个小案例我没写。


day21 8 ***全站编码问题***
装饰者模式的应用***
/*
 * 重点!!!
 * 如何解决get请求编码问题?
 * 我们采用装饰者模式,写一个request的装饰类。
 * 因为doFilter的参数会传递到目标资源中,所以我们可以
 * 调包request,即在放行时,使用我们自己的request
 * 
 * */
 可以将/day21_4/cn.itcast.web.filter中的两个类保存,应用到其他项目中只需该web.xml文件,就不用
 考虑编码问题了。(这里我将响应编码也放进去了,视频中只放了请求编码,响应编码还得在servlet中写)


 另一个问题:
 我们自己写一个装饰类EncodingRequest时,如果是实现HttpServletRequest接口,要实现太多的方法。
 解决办法是有一个好人HttpServletRequestWrapper,它已经帮我们实现了,只需继承它,然后重写某个
 需要装饰的方法即可。


day21 9-11 页面静态化
***核心思想:
这回我们对response进行装饰!!
对于一个JSP,默认在它真身里面都是用了response的getWriter向浏览器输出。
现在我们调包response,用我们自己写的response,对其getWriter方法进行装饰,使其向某路径下的
html文件输出。最后重定向到这个html。
注:为了解决html文件显示乱码问题,在jsp的<meta>标签加一个模拟响应头;
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">


实现以后效果:
第一次通过Servlet访问数据库,以后不访问servlet(因为被filter拦下了),直接重定向到一个html,
这样比较快。适合于页面长时间不变动的情况。




day22 5 文件上传代码演示
/*上传三步:
 * 1 得到工厂
 * 2 通过工厂创建解析器
 * 3 解析request,得到FileItem集合
 * 4 遍历FileItem集合,调用其API完成文件保存
 * */
 详见/day22_1


day22 7
Runtime run = Runtime.getRuntime();
这是个很危险的东西,run.exec()能执行一些dos命令,比如关机等。 
所以上传文件一般放WEB-INF下。除非是项目要用到,那就放项目的目录下,否则(比如放到了C盘),那把项目发
给客户的时候这个文件就不会带走了。
shutdown -s -t 300 五分钟后关机
shutdown -a 取消


day22 10 文件同名问题解决
filename = CommonUtils.uuid() + "_" + filename;


day22 11 目录打散
我们用的是哈希打散,每个对象的哈希码(一般不同),int类型
有点难度,我没写,详见视频


day22 12 上传文件大小限制
特别注意!!!上传处理不能用BaseServlet!!因为BaseServlet是基于getParameter方法来获取到底调用了
哪个方法,而这个方法在上传文件的时候是作废的!!


day22 15 文件下载
获得某文件的MIME类型:
String contentType = this.getServletContext().getMimeType(filename);
/*
 * 两个头一个流!
 * 1 Content-Type
 * 2 Content-Disposition
 * 3 流:下载文件的数据
 * */
最后 IOUtils.copy(in, response.getOutputStream());
注:谷歌浏览器不弹框,直接就下了。。。


day22 16 下载框中文件名乱码问题
考虑到不同浏览器版本,有一个比较万能的类DownUtils,详见截图。


day22 17 邮件协议
SMTP:简单邮件传输协议,发
POP3:邮局协议第三版, 收
邮件服务器名称(命名有规则的):
SMTP服务器端口号25,名称为smtp.xxx.xxx
POP3服务器端口号110,名称为pop3.xxx.xxx
如:smtp.163.com 和 pop3.163.com


day22 18 telnet发邮件
Xshell
Base64编码,和url编码一样不是字符编码!!编程奇奇怪怪肉眼无法识别的字符串!
怎么解决BASE64Encoder类不能用的问题?详见视频。


day22 19 javamail发送邮件
注意一个视频中没提到的问题,需要在邮箱中设置第三方授权密码,否则连不上smtp.163.com.
详见/day22_3


day22 20 带有附件的邮件
解决附件文件名称中文乱码问题,使用MimeUtility.encodeText();处理


day22 21 MailUtils
使用小工具简化邮件发送!!!真的简便多了...




day23 ajax
注意,POST请求的话需要自己设置一个请求头:Content-Type
get请求见 ajax1.jsp  post请求见ajax2.jsp


第三例:判断用户名是否已被注册,onblur事件发生时异步发送请求给服务器
这个例子我没写。
第四例:响应内容为xml
第五例:***省市联动***,比较复杂的一个例子,没写。


XStream
作用:可以把JavaBean转换为(序列化)为xml
把数据库查找的结果集转为对象我们已经学过,这里是进一步把对象转为xml,便于与ajax对接!


json-lib
JavaBean转为json!!!
依赖很多jar包,还没下载


其实重点掌握是JQuery封装好的ajax!!!见新加入的视频
$.get(4个参数)    $.post(4个参数)  
这两个都默认是异步请求,eval方法封装好了,不用自己写,Content-Type请求头也不用自己设置
$.ajax(json对象)


——————————————————————————————图书商城项目——————————————————————————————
小总结:
该项目采用JavaWeb三层架构,数据库使用MySQL,维护用户、图书、订单等五张表。项目实现用户登录校验、
邮箱激活、分类浏览、添加购物车、订单生成、第三方支付等功能,有必要时提供过滤器拦截页面。
管理员后台登录可对商品、订单进行管理。


普通超链接在<a></a>里面写文字就行
用图片做超链接在里面放<img>
要想实现鼠标悬停时改变样式(比如更换一张颜色更深的图片),<a></a>里面什么都不写,
在页面中设置CSS样式:比如(直接从项目中复制的):
a {
background: url(<c:url value='/images/all.png'/>) no-repeat;
display: inline-block;

background-position: 0 -70px;
margin-left: 30px;
height: 36px;
width: 146px;
}
a:HOVER {
background: url(<c:url value='/images/all.png'/>) no-repeat;
display: inline-block;

background-position: 0 -106px;
margin-left: 30px;
height: 36px;
width: 146px;
}


当用超链接提交表单时:
<form id="form" action="<c:url value='/CartServlet'/>" method="post">
  <input type="hidden" name="method" value="add">
  <input type="hidden" name="bid" value="${book.bid }">
  <input type="text" size="3" name="count" value="1"/>
  </form>
  <a href="javascript:document.getElementById('form').submit();"></a>
这样就能使提交按钮做出想要的效果




2.0-1.1 得到不是0.9,而是0.89999999999
Java中提供了BigInteger和BigDecimal处理精度丢失问题
double d1 = 2.0;
double d2 = 1.1;
BigDecimal d3 = new BigDecimal(2.0+"");
BigDecimal d4 = new BigDecimal(1.1+"");
System.out.println(d1-d2);
System.out.println(d3.subtract(d4).doubleValue());
这样就没问题了
值得注意的是,必须采用字符串的构造方法,否则还是一样丢失精度!!




用BeanHandler完成ORM映射时,若缺少字段,即select的时候只选了部分,一样能映射出一个对象,
只是部分值为null。
CommonUtils.toBean封装对象时,若给的Map含有多余的键值对,一样能封装成功,多余的忽略就行。




day27
*************注解*****************
给包上加注解可以,但是不能用普通方式。这东西没用不用管了。
注意:注解在Eclipse上显示的是灰色!以后看到灰色就要联想到注解!
当属性是一维数组只有一个元素时可以去掉大括号,这时候就容易混淆。比如:
f=100不知道f是int类型还是int[]类型去掉了大括号。得格外小心!


day28
动态代理
代理对象的所有方法都会调用InvocationHandler的invoke()方法,但有些方法除外:
这些方法是本地方法,即Object.class文件中标有native关键字的方法,如 getClass()


day28 7
****动态代理很有用的案例。


day28 9
类加载器的委托机制保证了程序的安全!比如如果你想写一个String类企图覆盖系统的String类,
门都没有,因为类加载器会先去找系统类库中的东西,找不到再找扩展的,再找不到才是你写的。


类加载器还得分线程,每一个线程有自己的类加载器负责加载。


小技巧:
要看一个方法调用栈,可以故意让它抛出异常(如果可以的话),这样异常信息就是调用栈了,
比debug快很多。


既然所有类都是类加载器加载的,那类加载器哪来的?都是由引导类加载器加载的。那引导类加载器又是
哪来的呢?答案是,它是JVM的一部分,相当于是自带的!







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值