day1 xml
1、xml中区分大小,并且会解析空格、换行
2、标签属性的等价写法<book type="java"> </book> 等价于 <book><type>java</type></book>
3、CDATA区放置不被解析器解析的内容,只会原封不动的输出。通常放置一些特殊代码 <![CDATA[ ............. ]]>
4、注意一些特殊字符的转义,比如< 等
day05
1、servlet是基于request-response编程的。servlet运行原理。你会发现,编写的servlet的java文件,是没有main函数的,那它是怎么运行的呢?是由tomcat调用的。
2、通过myeclipse的servlet引导可以创建servlet程序。修改servlet模板可以修改默认servlet文件生成样式。common/plugin/ com.genuitec.eclipse.wizards......
3、servlet生命周期。Servlet 的定义:
servlet 接口 -->实现类 GenericServlet -->子类 HttpServlet
解释:Sun在定义servlet接口的时候,并没有考虑什么协议,这是为了方便以后有不同协议可以继续扩展,所以在接口以及其实现类GenericServlet这里,并没有定义具体的协议。做web开发的时候,得需要HTTP协议,故定义了HttpServlet这个子类来进行。
Servlet生命周期:构造方法、init()、service()、destroy() 在tomcat启动过程中,servlet不会触发。当servlet第一次运行时,构造方法运行,构造实例;init()和service()先后运行。之后再运行servlet,都只是运行service方法。在容器正常关闭(指的是运行shutdown.bat)或重启的时候,运行destroy()方法。
每次运行一次servlet,都会开启一次新的线程,但是servlet的对象是独一的。应该是单例模式。
5、url-pattern 的三种方式:
(1) servlet-mapping里面 可以为一个servlet配置多个url-pattern地址
(2)servlet映射到URL中也可以使用通配符。一种是 *.扩展名 (例如 *.do 注意:绝对不能以/ 开头 ),另一种是目录匹配 /* (例如 /service/* )
插入知识点,出错的时候,查看caused by ,查看最后一个caused by
(3) 三种匹配的优先级 完全匹配 > 目录匹配 > 扩展名匹配
6、ServletConfig 获得初始化参数 : ServletConfig 存在于servlet 初始化的init( ServletConfig config)函数中,可以获取配置文件中当前servlet里面的
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
配置的参数。
实际上,GenericServlet中已经有一个函数 getServletConfig() 来获取ServletConfig了,所以其子类中可以直接用这个函数获取ServletConfig。有两个常用的函数获取初始配置的参数 getInitParameter() 和getInitParameters()
第一个是String类型 第二个是Enumeration<String>类型。Enumeration<String>类型其实就是Iterator的原型。所以其常用方法是 hasMoreElements() 和 NextElement()
另外注意:ServletConfig只能获取自己的Servlet内配置的初始参数,而不能获取其他Servlet里面的。
7、ServletContext : 这是针对一个工程(web应用)的上下文环境,有两种方法可以获取,一是 正规的方法,是通过ServletConfig 的 getServletContext()方法来获取的。
故有 ServletContext context = getServletConfig().getServletContext(); 第二个方法,在GenericServlet里面,已经用 getServletContext() 取代了getServletConfig().getServletContext()的返回值,故在GenericServlet的子类中,可以直接用getServletContext()来取得ServletContext.
ServletContext的第一个作用是取得web应用的全局参数,即配置在
<context-param>
<param-name></param-name>
<param-value></param-value>
</context-param>
里面的。类同ServletConfig 也有 getInitParameter() 和getInitParameters() 两个方法。
第二个作用是实现servlet之间数据共享
举例网站访问次数
使用setAttribute(String,Object) 和 getAttribute(String) 获取。注意getAttribute返回对象的转型问题,例 int num = (Integer) context.getAttribute(“count”);
第三个作用是重定向和转发
转发指的的是浏览器只发出一次请求,然后在web应用内部转发,所以路径是相对应于该应用内的。即 context.getRequestDispatcher(“/seven”).forward(request,response); 这是Request级的
重定向指的是,服务器让浏览器再次发出请求,其路径是针对于服务器的,即 response.sendRedirect("/day07/seven");这是Response级的。
第四个作用是读取资源文件
在java应用中,可以以相对目录地址的形式读取资源文件,但是在web工程中,必须以文件的绝对目录地址才能读到文件。
获取文件绝对地址的方法是 getServletContext().getRealPath(path) 其中path是相对目录地址。
@@ 因为WEB-INF/classes 非常特殊(存放.class文件目录),被类加载器加载,通过Class类对象读取该目录下文件。该方法也可以用于普通的java应用。
举例读取WEB-INF/classes/a1.txt
设在类ServletRead里, Class c = ServletRead.class; String RealFileName = c.getResource("/a1.txt").getFile(); 获取绝对路径 -- "注意,这里的/是指类路径 classpath 也即WEB-INF/classes/"
day06
1、服务器获得客户端信息 通过HttpServletRequest 对象 ; 服务器向客户端发送信息 通过 HttpServletResponse.
response 常用API:
setStatus 设置状态码
setHeader 设置头信息
getOutputStream 获得字节流 ---- 输出响应体内容
getWriter 获得字符流 ---- 输出响应体内容
2、常用状态码意义 :200 请求处理成功 302 客户端 重定向 304 客户端访问资源没有被修改,客户端访问缓存 404 访问资源不存在 500 服务器内部错误
302+Location实现重定向 response.setStatus(302); response.setHeader("Location","/day06/welcome.html");-------这两个其实用一个 response.sendRedirect()就可以替代。
3、自动刷新网页原理:通过refresh头信息 格式 ----- response.setHeader("refresh","时间;url=跳转路径");
HTML的META标签可以起到设置头信息的作用 <meta content="refresh","时间;url=跳转路径" http-equiv="refresh"> 可以起到同样效果
4、通过response头信息设置,禁止浏览器缓存。
原理:和禁用缓存相关的头信息有三个,分别是如下:
Cache-control:no-cache
Expires:Thu, 01 Dec 1994 16:00:00 GMT 因为这个比较复杂,一般用这个方法替代 response.setDateHeader("expires",-1); -1指的是毫秒,1970年前一秒。
Pragma:no-cache
5、字节流和字符流使用区别:拷贝文件用字节流,分析读取文件用字符流
response.setCharacterEncoding("utf-8") 设置响应内容编码,无法设置浏览器查看编码
response.setContentType("text/html;charset=utf-8") 设置响应内容编码,通知浏览器设置查看编码,用这一个就可以
getOutputStream 和 getWriter 两个互斥,不同共用。且使用时,必须在其之上设置响应编码。这两个方法输出内容是HTTP响应体,而不是头信息啥的。而且其内容是存在于缓冲区的,在service方法结束之后,自动关闭流,flush缓冲区内容。
6、文件下载。直接通过链接下载的不足之处:只有浏览器不识别的文件格式,才会弹出下载框。浏览器识别的文件格式,就会直接打开,比如图片。
通过servlet程序下载原理:通过servlet读取目标程序,将资源返回。
通过程序下载文件,需要设置两个头信息 Content-Type Content-Disposition
response.setContentType(getServletContext().getMimeType(filename)); ---- 设置文件类型
response.setHeader("Content-Disposition","attachment;filename="+filename); ----- 设置文件以附件形式下载
--------------------------------------------------------------------------
InputStream in = new FileInputStream(FullFileName); FullFileName指的是文件的绝对路径 getServletContext().getRealPath(path);
OutputStream out = response.getOutputStream();
int b;
while((b = in.read())!=-1){
out.write(b);
}
in.close();
out.close();
8、Request获得请求行相关数据
getMethod 得到客户机的请求方式
getRequestURL 返回客户端发出请求的完整URL http://localhost/day06/happy
getRequestURI 返回客户端发出请求行中的资源部分 -- 当前工程部分的地址 day06/happy
getQueryString 获得get查询字符串 参数部分
getRemoteAddr 返回发出请求的客户机IP
getContextPath 获得工程虚拟目录名称 day06
获得请求头信息 getHeader
获得请求体信息 getParameter 获得客户端参数信息 包括get和post信息
URI 包含 URL:URL一定是完整路径 而URI可以是相对路径
获得当前访问的资源路径 request.getRequestURI().substring(request.getContextPath().length()); happy
9、Request头信息获得与防盗链
获得请求头信息
getHeader 获得头信息的值,转换为一个字符串
getHeaders 获得头信息值,获得Enumration<String>
getHeaderNames 获得所有头信息名称,返回Enumration<String>
通过头信息的referer判断是否是盗链
String referer = request.getHeader("referer");
if(referer == null || !referer.startsWith("当前站点网址")){ 则证明是盗链 }
10、request获得请求参数
getParameter 通过单一表单name取值 String
getParameterValues 通过Checkbox的name值取值 String[]
getParameterNames 获得表单的name数组 Enumeration<String>
getParameterMap 获得Map方式的 Map<String,String> name -- value
注意非空校验 username != null && username.trim().length > 0
11、request请求参数乱码问题及解决
产生原因:前台客户端jsp页面假设是用UTF-8编码的,但是提交的数据到了服务器端,其是用ISO-8859-1解码的。这种解码叫做URL解码。
解决方法:对于POST方式,很简单,服务器端用request.setCharacterEncoding("utf-8")即可解决
对于GET方式,又分两种,一种是手动方式,服务器端先用ISO-8859-1编码,再用utf-8解码即可,即如下方式:
username = URLEncoder.encode(username,"ISO-8859-1");
username =URLDecoder.encode(username,"utf-8");
简化上面的写法:username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
第二种方法是修改tomcat的默认解码字符集 conf/server.xml 在connector 标签 同一行里 添加 URIEncoding="utf-8" 即搞定,就不需要手动了。但开始时尽量不要修改tomcat
结论,提交请求尽量用POST,非得用GET,就采用手动方法。
12、通过请求转发request域中的数据
HttpServletRequest和ServletContext 类似,都是数据域对象
通过request转发 即 request.getRequestDispatcher("path").forward(request,response); 可以将 通过request.setAttribute("key","value");所设置的值在一次请求中转发。
需要注意的是:
forward 和 SendRedirect不同同时使用,否则报错
在使用forward转发时,不得在其之前使用 response.getWriter().flush(),否则会报错。
同时,需要明白,不管是forward还是sendredirect,发生作用时,在其之前通过response.getWriter().print()方式写入内存缓存准备在客户端输出的内容,都会被清空而不会在客户端显示出来。
request和context的 RequestDispatcher的区别:context里面的路径,必须以“/”开始,是从root开始的绝对路径,而request的则可以用相对路径。
另外,通过RequestDispatcher的Include功能,还可以引入公用简化网页布局 request.getRequestDispatcher("footer.html");
day07
1、cookie快速入门
Cookie cookie = new Cookie(name,value);
response.addCookie(cookie);
2、服务器端获得cookie
Cookie[] cookies = request.getCookies(); --- 获得客户端所有cookie
if(cookies == null ){ } 判断cookie是否存在
for(Cookie cookie : cookies){
if(cookie.getName().equals("cookie名称")){ // find the cookie you want to get and do something..... }
}
Tomcat7.0出现java.lang.IllegalArgumentException: Control character in cookie value or attribute
这个是由于tomcat对中文的支持不够好,cookie直接把中文字符塞进去会出现此问题,可以先把中文用URLEncoder编码一下塞进去,在获取的时候,用URLDecoder.decode("%E4%BD%A0%E6%98%AF","UTF-8");解码后获取则行。
5、Cookie API详解与持久cookie的删除
getValue setValue getName 注意此三个方法
cookie信息默认是存储在浏览器内存中的,浏览器关闭则被清除。
通过setMaxAge设置cookie为持久cookie;cookie.setMaxAge(60*60*24) 设置cookie 有限期为一天
***在javaAPI中,所有和时间相关的,如果是int类型的,是秒;如果是long类型的,是毫秒。
生成cookie时,产生默认有效访问路径(默认生成cookie的程序路径)。
http://localhost/day07/c1 默认路径 /day07
http://localhost/day07/sms/c2 默认路径 /day07/sms --- 注意,该路径同时满足c1 c2,故会携带这两个cookie
如果访问的网址与cookie的路径不相符,cookie是不能被服务器读取的。
手动设置cookie.setPath("/day07");
一般而言,创建持久cookie,要setMaxAge和setPath
持久cookie的删除,设置setMaxAge为0即可,立刻删除(就等于重新定义一个cookie,只是这项设置为0,其余的setPath都要和要删除的cookie一致,然后response.addCookie 即可立刻删除)
6、session原理和常见问题
cookie保存在浏览器客户端,session保存在服务器端,每一个浏览器开一个session。有了session之所以还需要cookie,是考虑服务器压力的问题。
HttpSession session = request.getSession(); session.setAttribute("name",Object); Object obj = session.getAttribut("name");
测试实验及解决方法:
IE6在一个浏览器设置session后,关闭并另新开一个IE6浏览器,不能获得先前设置的session。IE8以上或Firefox不存在这个现象。
原因是IE6将Session的jessionid保存在会话级别的cookie中,关闭浏览器即消失。IE8以上或FireFOX则是将jsessionid保存在持久级别的cookie中。
解决方法,将jsessionid保存在持久cookie中即可。
HttpSession session = request.getSession();
Cookie cookie = new Cookie("JSESSIONID", session.getSessionId());
cookie.setMaxAge(60*60);
cookie.setPath("/day07");
response.addCookie(cookie);
7、session三种失效方法
第一种是修改web.xml
<session-config></session-config>
第二种是session.invalidate()
第三种是session.setMaxInactiveInterval(time) time为-1则永远不会失效
10、禁用cookie后URL重写的解决方法
原理就是把jsessionid附在URL上,随客户端访问提交到服务器,就可以得到session了。形如:http://localhost/servlet;jsessionid=34535235435 注意,是分号,而不是问号。
除此之外,解决的办法就是重写URL url = response.encodeURL(url) 然后再去使用这个url就会自动附上jsessionid了。
day08 jsp
1、<%! %> 定义翻译后的servlet程序的 全局变量或者全局方法、内部类
jsp原理是翻译成servlet执行的,比如 abc.jsp 是翻译成 abc_jsp.java的,存放在tomcat/work目录下
JSP注释 <%-- --%> 其在转化阶段即消失,在翻译成servlet时消失
2、JSP 指令
page指令 include指令 taglib指令 语法格式:<%@ 指令名称 属性=值 属性=值 %>
page指令标记详解
language="java" 默认就是java,写不写都一样
extends 这个是表示jsp文件翻译成servlet时候,要继续的类。默认是继续HttpJspBase这个类的。不需要理会。要是显式写了指令,赋予了其他的类,则jsp文件不会很好的翻译成java文件,必报错。
session="true" 默认就是这样的。这表示,在jsp文件翻译后的java文件里,有HttpSession session = null; 这个定义,所以才可以在jsp文件中,直接使用session这个变量,道理就在这里。如果等于false,则jsp文件中就没有session这个预定义变量了。同理application(ServletContext) request response 这几个变量都是在翻译后的java文件中预定义的。
import 导包的。注意jsp文件中的导包快捷键是 alt+/ 回车
buffer autoFlush 是用来设置out隐含对象属性的
buffer设置缓冲区大小 autoFlush设置缓冲区满的时候自动刷出
isELIgnored = "false" 默认支持。设置是否支持EL表达式
3、contentType和pageEncoding的区别
pageEncoding 是JSP源文件往硬盘上写的时候设置的编码集
contentType 是在servlet生成HTML 传递浏览器采用的编码
4、错误友好显示页面的设置
通过errorPage 设置发生错误跳转到的错误页面; isErrorPage="true" 告诉这个是预设值的错误页面。设置了isErrorPage了,就启用了Exception这个变量了,就可以用这个变量输出错误信息 Exception.getMessage();否则不启用。
开发中,更通常的做法不是这样。是通常设置web.xml来进行的,在这个xml中做如下定义
<error-page>
<error-code>404</error-code>
<location>404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>500.jsp</location>
</error-page>
根据错误的不同类型码,来设置不同的出错转向页面。
5、include指令标记
<%@ include file="footer.html" %> 是静态包含,等效于将包含的文件整个包含进去,与原文件一起翻译成一个servlet。包含的文件名不能是变量,不能有参数
<jsp:include page="文件路径" />是动态包含 可有参数。
6、JSP taglib指令使用
通过taglib指令引入jstl标签库,语法 <%taglib uri="" prefix="" %>
引用jstl时,在导入jstl.jar中 META-INF/c.tld <short-name>c</short-name> <uri>http://java.sun.com/jsp/jstl/core</uri>
7、jsp 九个内置对象 其本质是jsp在翻译成servlet时,在java文件中预定义好的变量。
page request response application(ServletContext) session pageContext out config(ServletConfig) excepiton
pageContext封装其他八大对象,其用处主要是为了编写框架方便。
out.print() 和 response.getWriter().print()之区别:
out对象是JspWriter类型 out = pageContext.getOut();
response.getWriter() 返回PrintWriter对象
举例1:
out.print("aa");response.getWriter().print("bb");out.print("cc"); 输出结果 bb aa cc
out.print("aa");out.flush();response.getWriter().print("bb");out.print("cc"); 输出结果 aa bb cc
8、jsp中六个动作标签
<jsp:useBean><jsp:setProperty><jsp:getProperty> -- 与javaBean操作相关
<jsp:include page=“” />参看第五节
<jsp:forward page="" ><jsp:param name="" value=""></jsp:forward>等效于 request.getRequestDispatcher("path").forward(request,response);