1 Servlet
1.1 Servlet
-
以线程方式处理请求;cookie处理:二次访问时,浏览器会将cookie发送到服务器;侧重控制逻辑
-
Servlet = Java + HTML
-
Servlet / ServletConfig接口
-
GenericServlet:实现上面两个接口的类;协议无关
-
HttpServlet:基于http协议实现类;编写的Servlet都继承自此类,标注请求URL
-
自定义类实现doGet/Post():如SpringMVC的DispatcherServlet
-
-
Servlet方法与生命周期:初始化后调用一系列doXXX()
-
方法参数:HttpServletRequest,HttpServletResponse
-
获取参数:request.getParameter(string)
-
设置Attribute:request.getSession().setAttribute(key,value)
-
转发:request.getRequestDispatcher(path).forward(request,response)
-
重定向:response.sendRedirect()
-
-
init(servletConfig):调用配置类初始化Servlet
-
默认第一次访问Servlet时创建;自定义时机可通过web.xml修改,如DispatcherServlet就是在启动容器时创建;< load-on-startup>
-
单例,只创建/初始化/销毁一次
-
非线程安全:多个http请求线程访问同一个Serlvet对象,并发调用service(),需要考虑线程安全问题
-
-
getServletConfig():Servlet配置信息
-
service(servletRequst,servletResponse):如doGet(),doPost()
-
getServletInfo():Servlet相关信息如作者,版权
-
destroy():销毁
-
异常:ServletException,IOException
-
-
ServletConfig:Servlet配置信息;如标签< init-param>实现参数初始化
-
getServletName():< servlet-name>
-
getInitParameter():获取配置参数;servlet标签下有< init-param>
-
getInitParameterNames()
-
getServletContext():关联ServletContext类
-
-
HttpServlet:
-
重写service():将sevletRequest/servletResponse转为httpServletRequest/httpServletResponse;根据http请求方法路由到7个不同处理方法
-
getLastModified(httpServletRequest)
-
doGet/Head/Put/Delete/Options/Trace/Post(httpServletRequest,httpServletResponse)
-
诸多封装类获取信息头,如Cookie[] getCookies();Enumeration getAttributeNames()返回请求中所有属性的名称集合,getParameterNames()参数集合;HttpSession getSession()没有则创建;String getRequestURI()
-
new Cookie(name,value);一个cookie(客户端保存的一小段文本)通常包含一个键值对(被解析为URL),一个GMT格林尼治时间,一个路径,一个域名;获得或者新建cookie以后,get/setMaxAge()/Name()/Value()/Path()…;然后添加到response.addCookie(cookie);删除cookie:手动浏览器删除,或者获取后有效期设为0,添加到response
-
-
HttpServletRequest:
-
getScheme():请求协议
-
getServerName():服务器名;本机返回localhost
-
getServerPort():服务器端口号,Tomcat默认8080
-
getContextPath():应用上下文的入口url;一般为“/项目名”
-
getRequestURL():完整请求路径
-
1.2 会话跟踪技术
-
http状态码:200;3xx暂时转发;400BadRequest;403Forbidden;404NotFound;405MethodNotAllowed;408RequestTimeout;500ServerError
-
(请求)转发:
-
request.getRequestDiapatcher("/my.jsp").forward(request,response)
-
发生在服务器内部的跳转,即内部方法调用;前后共用request;可设置传递的数据或session,request.setAttribute()
-
对于客户端来说始终是一次请求,url不变
-
可理解为我不能处理,但我带着数据帮你去找可以处理的请求
-
-
(响应为)重定向:
-
response.sendRedirect("/index.jsp")
-
发生在客户端的跳转,即两次不同的请求,不共用request,url改变
-
数据传递可以使用session,在第二个文件中删除session;也可以使用带参数的url
-
对数据增删改的时候,如果要跳转,则应该重定向
-
可以理解为我不能处理,但我响应你正确的请求,你重新发送请求
-
-
cookie:
-
sessionId标识,存在客户端,一般最大4K,随浏览器关闭而消失;不安全
-
隐藏的表单字段,URL重写,仅存储字符串,转为json使用
-
可设置有效期来做非会话级cookie如3天免登录功能
-
httpOnly=true防止客户端的XSS攻击/跨站脚本攻击,但主要还是需要后端过滤
-
path="/"设置访问路径
-
domain=""设置cookie域名
-
-
session:
-
HttpSession接口,安全;保存任意类型数据,存储在服务器,30分钟有效即浏览器关闭后session并不会消失
-
记录用户状态:如session.setAttribute("user", user),因为服务器自动为会话级cookie生成标识jsessionId
-
attribute被设置在request中,则仅当前request有效;设置在session中则在有效期间都被共享
-
getParameter()系列方法是从前端页面或url参数中获取数据
-
get/set/removeAttributeNames;getCreationTime();getId();invalidate()丢弃整个session会话;setMaxInactiveInterval(int)设置过期时间(秒)
-
1.3 请求与相应
-
Web服务器收到客户端的http请求,针对每一次请求,分别创建用于代表请求的request对象,和代表响应的response对象
1.3.1 HttpServletResponse
-
response对象,setXXX()方式覆盖原来属性的值;addXXX()方式会添加属性:包含
-
响应头:setHeader(),包括setDateHeader()自动转日期的,setIntHeader()字符串转为数字的
-
Content-type:设置互联网媒体类型即MIME类型(写为content-type就变成了下载?????)
-
response.setHeader("Content-type", "text/html;charset=utf-8") 等同于 setContentType("text/html;charset=utf-8")
-
text/html:html格式
-
text/plain:纯文本格式
-
text/xml:xml格式
-
image/gif或jpeg或png:图片格式
-
application/xhtml+xml:XHTML格式
-
application/xml:XML数据格式
-
application/atom+xml:Atom XML聚合格式
-
application/json:JSON数据格式
-
application/pdf:pdf格式
-
application/msword:Word文档格式文件下载,或者application/x-msdownload,适用于IE,Firefox,Google
-
application/octet-stream: 二进制流数据,常见的文件下载;外加Max上的Safari
-
application/x-www-form-urlencoded : < form encType="">中默认的encType,form表单数据被编码为key/value格式发送到服务器
-
multipart/form-data: 上传文件时使用
-
charset=UTF-8:设置客户端打开数据时的编码方式;区别于response.setCharacterEncoding("UTF-8"),这是控制response的响应数据的编码方式,默认为ISO-8859-1
-
MIME扩展:
-
Content-disposition:控制用户请求所得的内容存为一个文件时,提供一个默认的文件名,文件直接在浏览器上显示,或者在访问时弹出文件下载对话框;根据不同的MIME调用不同的程序嵌入模块来处理数据
-
attachment:以附件方式下载
-
disposition-parm:为默认保存时的文件名
-
服务端向客户端发送文件时,如果是客户端支持的文件类型,一般会默认使用浏览器打开,如txt、jpg
-
-
下载的文件名或内容乱码问题:response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GBK或UTF0-8"), "ISO8859-1"))
-
-
-
-
-
响应状态码:setStatus();302-重定向;304-访问缓存;404-地址错误;500-服务器错误;推荐使用其中的状态码常量
-
响应数据:getWriter(),getOutputStream()
1.3.2 HttpServletRequest
-
request对象
-
配合一些封装类处理,如RequestContextHolder,ServletRequestAttributes
-
request.getParameterMap(); // 将请求中的参数封装为map形式
-
getRemoteAddr() 或 getHeader("X-FORWARDED-FOR"):获取访问服务器的请求所在电脑的IP
-
项目路径与Tomcat路径获取
String realPath = request.getServletContext().getRealPath("/"); String realPathParent = (new File(realPaht)).getParent(); String classPath = this.getClass().getResource("/").getPath().replaceFirst("/", ""); String webAppPath = classPath.repalceAll("WEB-INF/classes", "");
-
1.4 过滤器
-
Filter:动态拦截请求和响应,修改和使用其中的信息
-
应用:防盗链,日志记录,字符替换,异常捕获,用户及权限验证,字符编码,弹出对话框形式的公告信息,文件上传,数据压缩,加密,触发资源访问事件,图像转换等
-
项目安全性:
-
攻击性安全:input框JS验证,java代替重复校验,避免非法字符和空格和SQL注入;特殊模块的时间限制,如登录时生成验证码,支付时产生随机码
-
访问安全:页面静态化,使用缓存,减小服务器压力
-
数据安全:数据库敏感数据加密后存储;数据库读写分离;备份
-
-
定义过滤器:web.xml中声明,映射到Servlet或URL
-
< filter-name>< filter-class>;定义
-
< init-param>:设置初始化参数<param-name/value>
-
< filter-mapping>:映射
-
< filter-name>< url-pattern>:需要拦截的Servlet路径
-
-
-
文件上传:< form method="post" action="servlet" enctype="multipart/form-data"> <input type=”file”…
1.5 实例
-
金额数字转为汉字:
-
字符串转为数组:
// 前端复选框值被js设置为长字符串
var checks=document.getElementsByName(“ckeck”);
var string=””;
for(var i = 0; i < checks.length; i++) {
if(ckecks[i].cheacked == true) {
string += checks[i].value + ",";
}
}
// 隐藏表单域提交到后台
document.getElementById(“string”).value = string;
// 后端通过String的slit(regex)以regex表示的符号切割长字符串为字符串数组
-
POI组件将数据导出到Excel表:
response.setContentType(“application/vnd.ms-excel”);
ServletOutputStream out = response.getOutputStream();
HSSFWorkbook wb = new HSSFWorkbook(); // 创建excel表格
HSSFSheet sheet = wb.createSheet(“数据”); // 创建工作簿
sheet.setColumnWidth(4,5000); // 设置列宽
HSSFRow titileRow = sheet.createRow(0); // 标题行
HSSFCell titleCell = titleRow.createCell(0); // 标题行的第一个单元格
titileCell.setCellValue(“用户名”);
// …n个单元格
HSSFRow valueRow = sheet.createRow(1); // 创建第二行
// …对应n个单元格且设值
wb.write(out);
out.flush();
out.close();
2 JSP
2.1 JSP
-
本质是servlet:JSP -> 翻译 Servlet/Java -> 编译 -> .class
-
JSP(侧重视图) = HTML(侧重视图展示) + Java(侧重实现控制逻辑);动态生成html、xml或其他格式文档的web页面,即html中插入java代码(被JSP标签<% %>包裹);跨平台
-
JSP生命周期:
阶段 说明 1. 加载 web容器识别这是对JSP的请求,通过url或.jsp文件把此请求交给JSP引擎 2. 编译 解析JSP文件,转为servlet程序;servlet容器编译源文件为字节码类文件 3. 初始化 创建实例,调用初始化方法init();仅一次,可初始化数据路连接,打开文件,创建查询 4. 执行 调用服务方法service();参数为HttpServletRequest和HttpServletResponse;每个请求都调用一次,产生对应的response 5. 销毁 调用销毁方法destroy()销毁实例 -
表达式:<%= …/>
-
注释<%--…-->或者<!-- -->
-
JSP三个指令:
指令语法 说明 <%@ page…/> 依赖属性,如脚本语言、error页面、缓存需求
buffer缓冲区大小
autoFlush控制out的刷新
contentType;errorPage;isErrorPage;extends;import(注意没有<jsp:import>)
isThreadSafe本页面访问是否线程安全/单线程,而servlet实现单线程需要实现SingleThreadModel接口;不推荐单线程,它会对每次请求都创建实例
language;session是否使用
isELlgnored是否执行EL表达式;isScriptingEnabled
<%@ include file=”相对url”…/> 包含其他文件,然后编译 <%@ taglib…/> 引入标签库 -
JSP 9个行为:请求处理时发生,它们都具有id(动作的唯一标识)和scope(动作的生命周期:page-request-session-application)属性
语法 说明 <jsp:include [page=”url.jsp” flush=””]...> 包含静态动态资源;动态加载即不是同时编译 <jsp:useBean id=”” class=”Bean的完整包名”[type beanName] 加载并初始化JavaBean组件 <jsp:set/getProperty name=”useBean的id” property=”*或者具体(类的)属性” [value=”属性值” param=”用具体的请求参数做值”] 设置/插入JavaBean组件到output;当其位于<jsp:userBean内部的时候,必须先创建Bean实例;否则无论有没有加载Bean,都会执行;此行为等同于java的类调用getter方法:<% =UseBean.get属性()%> <jsp:forward page=”anotherJSP” 转发(包含request对象);可带参数<jsp:param name=”userId=”1”/> <jsp:plugin 使用插件运行 <jsp:element 动态创建xml元素 <jsp:attribute 定义xml元素的属性 <jsp:body xml主体 <jsp:text 封装模板数据 -
JSP 9个对象:
对象 说明 request HttpServletRequset实例,通过方法获取http头信息,cookie,http方法等 reponse HttpServletResponse实例,可添加cookie,时间戳,状态码;void setHeader()/setLocal()/setStatus();… session HttpSession实例,会话跟踪,保存用户状态信息 out PrintWriter实例,向response中写入内容,输出结果到页面 application ServletContext实例,应用上下文 config ServletConfig实例,一些配置信息 pageContext PageContext实例,存储其他对象的引用;常用方法removeAttribute() page 类似于this对象,页面本身 exception Exception实例,JSP发生错误时的异常;异常处理:使用此对象的方法;或者编写errorPage;或者java的try…catch -
表单处理-读取表单数据:
-
get:默认方式;参数在url?后,&连接,不安全,<=1024字节
-
post:数据隐藏提交,无大小限制,安全;request.getParameterValues / getParameterNames();getInputSteeam()
-
2.2 JSTL
-
JSP标签库
<%@ taglib prefix=”c” uri=http://java.sun.com/jsp/jstl/core />;
<c:out/set/remove>:显示,同<%= >/保存/删除数据;
<c:catch>:处理异常;
<c:if/forEach>;
<c:choose>,其下<c:when><c:otherwise>条件分别为true和false;
<c:import/para/redirect/url>;
// 解析和格式化(文本、日期、时间、数字)标签:core换为fmt且更改前缀;
<fmt:parseNumber/formatNumber>
<fmt:parseDate/formatDate>
……
SQL标签:sql下:<sql:getDataSource/query/update/param/transaction>,其下写sql的CURD;
XML标签:以及JSP的XML处理;
JSTL函数:functions下:<fn:indexOf()/……等常用字符串处理函数;
自定义标签
2.3 EL表达式
-
${expr};简化JavaBean的访问;expr通常为算数表达式和逻辑表达式,操作符如同java,如+,-,%,!=,>=,||(or),empty……;特殊的如用.userName或者[“username”]访问Bean属性
-
隐含对象:pageScope / requestScope / sessionScope / applicationScope:各自的作用域中的对象直接访问,如requestScope.user
-
param / paramValues:request对象的参数,字符串/集合;如String name = request.getParameter(“username”),用EL表达式获取${param[“username”]}或者${param.name}
-
initParam:上下文初始化参数
-
header / headerValues:http信息头,字符串/集合;同上;request.getHeader()
-
cookie:
-
pageContext:JSP中pageContext对象的引用
-
实例:获取表单中多选框的值:
var checkbox = document.getElementsByName(“checkbox”); for(i < checkbox.length) { if(checkbox[i]).checked) alert(checkbox[i].value); // 或者声明一个数组new Array()来保存值 } // js String[] arr = request.getParameterValues(“checkbox”);
2.4 实例
-
自定义错误页面:页面异常时跳转:
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8” errorPage=”error.jsp”%> <% page isErrorPage=”true”%> // 针对指定网页 <error-page> // web.xml配置针对所有页面 <error-code>404</error-code> <location>/error.jsp</location>
-
java片段动态生成表格/下拉列表:
<% String[] arr={“…”,”…”,…} %> <table border=”1” align=”center”> <tr> <td>字段1</td> <td>字段2</td> </tr> <% for(int i = 0; i < arr.length; i++) { %> <tr> <td> <% =i %> </td> <td>< %= arr[i] %> </td> </tr> <% } %>
-
获取表单提交信息/(超链接)访问请求参数:
<a href = ”delete.jsp?id=1”> request.setCharacterEncoding(“UTF-8”); String str = request.getParameter(“表单域<input>的name值”);
-
request域传递数据-转发:
equest.setAttribute(key,value); // key为String类型,value为传递的值如object,“404错误” request.getAttribute(key); // 通过key获取
-
cookie保存和获取信息(name-value形式):
Cookie[] cookies = request.getCookies(); // 从request获取对象集合 for(Cookie cookie: cookies) { cookie.getName(); // 获取指定cookie名 cookie.getValue(); // 获取值 cookie.setMaxAge(long); // 有效期 Cookie c = new Cookie(name,value); // 实例化一个cookie对象 response.addCookie(c); // 保存cookie[发送到客户端] } // cookie中保存中文: java.net.URLEncoder.encode(name,”UTF-8”); // 编码 java.net.URLDecoder.decode(name); // 解码
-
Application对象(生命周期随服务器)实现网站访问计数器:
<% int count =0; synchronized(application) { if(application.getAttribute(“times”) == null){ i++; // 首位访问 } else { i = Integer.parseInt((String)application.getAttribute(“times”)); i++; } application.setAttribute(“times”,Integer.toString(i)); %>
-
session相关:
-
保存用户登录信息,页面跳转后从session获取信息;手动销毁session:session.invalidate()
-
统计用户在站点的停留时间:继承session的监听器(session与属性的绑定与解除事件)HttpSessionBindingListener的主要方法valueBound()和valueUnbound(),前者在向session中写入实现类对象时自动触发,后者在从session中移除对象时触发;session销毁时间-创建时间
-
统计在线人数
-
3 JDBC
-
Driver:加载数据库驱动(jar包);Class.forName(“”);
-
DiverManager:管理JDBC驱动服务类,获得数据库连接:DiverManager.getConnection(url, user, password);
-
Connection:数据库连接对象,创建Statement对象
Statement createStaetment(); PrepareStatement prepareStatement(sql); CallableStatement prepareCall(sql); Savepoint setSavepoint([name]); // 创建保存点 void setTransactionIsolation(level); // 设置事务隔离级别 void rollback([savepoint]); // 回滚(到保存点) void setAutoCommit(boolean); // 关闭自动提交,打开事务;因为Connection默认会自动提交,即关闭事务 void commit(); // 提交事务
-
Statement:执行SQL语句,涉及批量更新方法
-
PreparedStatement:安全,防SQL注入(如永真表达式),in参数,占位符,预编译SQL语句即下面的方法不传入sql参数,新增void setXxx(parameterIndex, value))
-
CallableStatement:out参数,调用存储过程
-
ResultSet excuteQuery(sql):操作结果集
-
操作指针指向数据:absolute(row)row行;beforeFirst()初始状态,首行之前;first()首;previous()上一行;next()下一行;last()尾行;afterLast()尾行之后
-
通过索引或列名获得列数据:getXxx(index/string)
-
boolean excute(sql)
-
结果集从1开始;可回滚
-
-
int excuteUpdate(sql);:受影响行数为0或没有结果,返回false
-
回收和关闭资源
-
SQLException:应用无法连接数据库;查询语法错误;查询目标表或列不存在;插入或更新的数据违反数据库约束
-
处理blob类型数据:PrepareStatement的setBinaryStream(parameterIndex, inputStream)保存数据到数据库;ResultSet的getBlob(columnIndex)取出得到blob对象,对象的getBytes()获取数据,或getBinaryStream()获取数据的输入流
-
最佳实践:
-
批量操作
-
使用PreparedStatement避免SQL异常
-
使用数据库连接池
-
通过列名获取结果集而不是下标
-
-
数据库连接:
-
模板:消除冗长的JDBC编码
-
JdbcTemplate(推荐):基于索引参数的查询;NamedParameterJdbcTemplate:值以命名参数形式绑定到SQL;SimpleJdbcTemplate(废弃):自动装箱、泛型和可变参数
-
构建以dataSource为参数且返回模板对象的模板bean
-
tx:annotation-driven:事务驱动(spring通过AOP实现事务的根本原因);配合AOP配置相关事务操作
-
实现DataSource的bean(使用配置中的参数)的Connection, Statament以及CURD, ResultSet @Repository(标注参与数据库操作的bean)的bean中引入模板类,在@Inject处自动注入;执行CURD方法(提供参数即可,模板类自动获取连接、创建语句和执行SQL)
-