一、JSP:Java Server Page是一种运行在服务器端的Java页面
1、使用能够JSP实现输出:
1-1:JSP对象输出显示
out.prin(); 向页面输出显示
out.println(); 向页面输出显示,在末尾加个空格
★换行只能是<br/>
1-2:JSP注释
HTML注释:<!-- HTML注释 -->,显示在源代码
JSP注释:<%-- JSP注释 --%>,隐藏在源代码
JSP脚本注释:<% //JSP单行注释 %>、<% /**JSP多行注释*/ %>,隐藏在源代码
1-3:转义字符
\" \":引号引起来
1-4:JSP中声明和使用变量:<%String 变量名="内容";>
1-5:用变量实现页面输入:<%=变量名 %>
1-6:使用<%@page %>导包
1-7:<%%>:局部变量
<%!%>:全局变量
1-8:Web程序常见的错误
1>404错误——找不到访问的页面或资源
A:运行时,URL输入有误
B:将页面放在WEB-INF下
C:外部启动Tomcat,未部署项目
2>500错误——JSP页面代码有误
3>页面无法显示:未启动Tomcat
2、内置对象:JSP已经准备好的,可以直接使用的对象
2-1:请求对象:request(客户端发送请求)
2-2:输出对象:out
2-3:响应对象:response(服务器接受请求——200状态码)
2-4:应用程序对象:application
2-5:会话对象:session
2-6:页面上下文对象:pageContext
2-7:页面对象:page
2-8:配置对象:config
2-9:异常对象:exception
3、request对象常用方法
3-1:String getParameter(String name):根据表单组件名称获取提交数据
3-2:String[] getParameterValues(String name):获取表单组件对应多个值时的请求数据
3-3:void setCharacterEncoding(String charset):指定每个请求的编码
3-4:RequestDispatcher getRequestDispatcher(String path):返回一个RequestDispatcher对象,该对象的forward()方法用于转发请求
4、页面间的数据传递
4-1:使用属性存取数据
1>setAttribute():在请求中保存属性
public void setAttribute(String name,Object o);
2>getAttribute():在请求中获取属性
public Object getAttribute(String name);
★在读取属性中保存的数据时,必须将数据转换成其最初的类型:String mess=(String)request.getAttribute("mess");
在使用属性值的时候要做非空判断,否则会出现空指针异常
4-2:转发与重定向
1>转发:是服务器行为——RequestDispatcher对象、forward()方法(1个请求,返回200状态码,失败时返回页面)
语法:A:request.getRequestDispatcher("url").forward(request,response);
B、<jsp:forward page="url" />
2>重定向:是客户端行为——将用户请求重新定位到一个新的URL(2个请求,第一个返回302状态码,第二个返回200状态码,成功时转到另一个页面)
语法:response.sendRedirect("url");
5、Session会话对象:数据保存在服务器
5-1:Session保存和读取数据的方法
使用Session保存数据:session.setAttribute(String key,Object value)
从Session中读取数据:(Object)session.getAttribute(String key);
5-2:Session对象常用方法(单用户)
getId():获取sessionId
invalidate():设置session对象失效
setMaxInactiveInterval(int interval(单位:秒)):设置session的有效期
removeAttribute(String key):移除session中的属性
5-3:Session的有效期
在Tomcat服务器的web.xml文件中<web-app>和</web-app>之间添加:
<session-config><session-timeout>分钟</session-timeout></session-config>
6、Cookie:以文件方法保存数据的,保存在客户端
6-1:Cookie的应用(在JSP中使用Cookie)
1>创建Cookie对象
Cookie cookieName=new Cookie(String key,Object value);
2>写入Cookie
response.addCookie(cookieName);
3>读取Cookie
Cookie[] cookies=request.getCookies();
6-2:Cookie常用方法
setValue(String value):创建Cookie后,为Cookie进行赋值
getName():获取Cookie的名称
getValue():获取Cookie的值
getMaxAge():获取Cookie的有效期,以秒为单位
setMaxAge(int expiry):设置Cookie的有效期,以秒为单位
6、application:实现统计页面的访问次数(多用户共享)
setAttribute(String key,Object value):以key-value的形式保存对象值
getAttribute(String key):通过key获取对象值
7、request、session、application三个对象对比
相同点:都可以存储属性
不同点:request中存储的数据仅在一个请求中可用
session中存储的数据在一个会话的有效期内可用
application中存储的数据在整个Web项目中可用
二、JDBC和JavaBean操作数据库
1、JDBC是一中Java数据库连接技术,能实现Java程序对各种数据库的访问。
2、JDBC访问数据库的五步骤:
2-1:加载驱动(找到jar包→com.msyql.jdbc→Drivere.class)
Class.forName("JDBC驱动类的名称");
★mysql:com.mysql.jdbc.Driver
oracle:oracle.jdbc.driver.OracleDriver
2-2:使用DriverManager类获取数据库的连接
Connection connection=DriverManager.getConnection(数据库URL,数据用户名,密码);
★mysql 的URL:jdbc:mysql://localhost:3306/数据库名
oracle的URL:jdbc:oracle:thin@localhost:1521:数据库名
2-3:获取Statement对象,执行sql语句
1>定义sql语句:String sql = "select * from 表名";
2>先创建Statement接口:Statement st = connection.createStatement();
3>获取结果对象:ResultSet rs = st.executeQuery(sql);
2-4:处理结果
while (rs.next()){ }
2-5:释放资源
rs.close();
st.close();
connection.close();
3、设置配置文件
3-1:创建database.properties文件
3-2:构建数据库访问的工具类,来读取配置文件
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//读取配置文件的工具类-单例模式
public class ConfigManager {
// 读取配置properties.load(inputStream)
private static ConfigManager configManager;
private static Properties properties;
// 在构造工具类时,进行配置文件的读取
private ConfigManager() {
String configFile = "database.properties";
properties = new Properties();
InputStream is = ConfigManager.class.getClassLoader()
.getResourceAsStream(configFile);
try {
// 读取配置文件
properties.load(is);
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 通过单例模式设置实例化的个数
public static ConfigManager getInstance() {
if (configManager == null) {
configManager = new ConfigManager();
}
return configManager;
}
// 通过key获取对应的value
public String getString(String key) {
return properties.getProperty(key);
}
}
4、Statement与PreparedStatement区别
4-1:Statement由方法createStatement()创建,该对象用于发送简单的sql语句
sql语句用“?”作为数据占位符、使用setXxx()方法设置数据
5、连接池与数据源
5-1:连接池、连接、数据源的关系
1>连接池:里面放着连接对象,并管理连接对象的(连接对象是保持与数据库连接的)
2>数据源DataSource:用来获取连接对象,连接数据库(直接从数据源中获取连接)
3>如何获取DataSource:由Tomcat容器创建,在程序里使用JNDI来获取
4>通过数据源创建的连接对象被统一的放入到连接池中进行管理
5-2:在Toacat中配置数据源步骤:
1>Tomcat中加入数据库驱动文件
2>配置Tomcat的conf/context.xml
<span > </span><Resource name="jdbc/news"
auth="Container" type="javax.sql.DataSource" maxActive="100"
maxIdle="30" maxWait="10000" username="root" password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/news"/>
★name:数据源名称,通常采取 jdbc/数据库名
auth:连接池的归属权
type:类型
maxActive:并发连接的最大活动数。 0:无限制
maxIdle:连接池中空闲的连接的个数
maxWait:等待连接的最大连接的时间 -1:无限等待下去
username、password:数据库用户名、密码
driverClassName:驱动程序名称
url:访问数据库路径
3>使用JNDI获取连接对象
A、 初始化上下文
Context ctx = new InitialContext();
B、获取与逻辑名相关联的数据源对象
DataSource ds = (DataSource) ctx.lookup("java:comp/env/数据源名称");
connection = ds.getConnection();
4>调用数据源得到连接
需要实例化获取数据源方法所在类,然后调用获取数据源的方法就可以得到一个Connection对象
6、JavaBean:是一个java类。封装数据、业务逻辑
DAO层:对数据进行增删改查操作,访问数据接口
util层:读取配置文件的工具类
service层:业务层,负责业务逻辑,对dao的方法进行封装调用,主要负责和业务逻辑相关的操作
7、JSP标签
7-1:JSP动作标签
1><jsp:useBean>:在JSP中创建一个JavaBean的实例,并指定它的名称和作用范围,可发挥Java组件重用的优势
语法:<jsp:useBean id="name" class="package.class" scope="scope">
id:JavaBean的引用名
class:JavaBean类的完整限定名
scope:JavaBean的作用范围,默认page
7-2:JSP页面包含:把指定文件插入正在生成的页面
1>动态包含:先执行页面代码,再将页面包含,即将一个页面的运行结果包含到另一个页面上
语法:<jsp:include page="相对URL地址" />
2>静态包含:先将页面包含,再执行页面代码,即将一个页面的代码复制到另一个页面上(适用于公共的CSS、JS代码)
语法:<%@include file="url" %>
7-3:JSP页面跳转
<jsp:forward page="URL" />
三、第三方控件与分页查询
1、第三方控件:commons-fileupload(Java的)
1-1:FileItem接口的常用方法
1>getFieldName():返回表单字段的name属性值
2>isFormField():判断FileItem封装的数据是属于普通表单还是文件表单 true:普通表单 false:文件表单
3>getName():返回上传文件字段中的文件名
4>write(File file):将FileItem对象中的内容保存到指定文件中
5>getString(String encoding):按照指定编码格式将内容转换成字符串返回
1-2:FileItemFactory接口与DiskFileItemFactory类
1>FileItemFactory是一个接口,是用于构建FileItem实例的工厂
2>DiskFileItemFactory类是FileItemFactory接口的实现类,在使用中,可以构造一个FileItemFactory接口类型的实例:
FileItemFactory factory=new DiskFileItemFactory();
1-3:ServleFileUpload类:用于处理文件上传的核心类,
1>作用:以List形式返回每一个被封装成FileItem类型的表单元素集合
2>构造语法:public ServleFileUpload(FileItemFactory fileitemfactory)
3>常用方法
A、isMultpartContent(HttpServleRequest request):静态方法,用于判断请求数据中的内容是否是multipart/form-data类型
B、parseRequest(HttpServleRequest request):将请求数据中的每一个字段,单独封装成FileItem对象,并以集合方法返回
2、使用commons-fileupload组件实现图片上传步骤
2-1:获取组件
commons-fileupload-1.2.2.jar、commons-io-2.4.jar
2-2:修改页面
1>修改表单:method="post" enctype="multipart/form-data"
2>设置上传文件的标签:<input type="file" name="picPath" value="" />
2-3:在JSP中实现文件上传
1>判断表单提交内容形式
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
if (isMultiPart){ 处理文件上传}
2>创建文件谁能够穿所有的API实例
创建FileItemFactory实例:FileItemFactory factory = new DiskFileItemFactory();
创建文件上传的核心类ServletFileUpload:ServletFileUpload upload = new ServletFileUpload(factory);
3>解析request请求
List<FileItem> items = upload.parseRequest(request);
4>循环遍历集合中的数据
//获取迭代器
Iterator<FileItem> iters = items.iterator();
while (iters.hasNext()) {
FileItem item = iters.next();
//判断fileItem是文本域还是文件域
if (item.isFormField()) {//若是普通的文本表单控件
//获取文本域name的值
String fieldName = item.getFieldName();
if (fieldName.equals("categoryId")) {
news.setCategoryId(Integer.parseInt(item.getString()));
} else if (fieldName.equals("title")) {
news.setTitle(item.getString("utf-8")); //获取文本域value的值
}。。。。。。
} else {//若是文件表单控件
//上传文件名称(全路径)
String fileName = item.getName();
//userId+系统时间+随机数.doc
if (fileName != null && !fileName.equals("")) {
File fullFile = new File(fileName);
//把文件上传到指定的目录下
File saveFile = new File(uploadPath,fullFile.getName());
//上传操作
item.write(saveFile);
news.setPicPath(fullFile.getName());
}
}
}
3、CKEditor:网页中实现所见所得的编辑器(JS的)
3-1:使用步骤
1>下载CKEditor
2>解压到项目到WebRoot中
3>在页面中加入CKEditor:<script src="<%=request.getContextPath() %>/ckeditor/ckeditor.js" ></script>
4>修改页面的<textarea>的属性: 添加"class=ckeditor"
5>使用→提交
4、分页查询
4-1:分页后台实现
1>确定显示数据总数量:
sql语句:select count(*) as count from 表名;
通过JDBC进行SQL语句执行:Object[] params = {};
ResultSet rs = this.executeSQL(sql, params);
获取总记录数:int count = rs.getInt("count");
2>计算显示页数
package com.util;
public class PageSupport {
//总页数
private int totalPageCount = 1;
//总记录数
private int totalCount = 0;
//当前页面
private int currentPageNo = 1;
//页面容量(每页显示多少条)
private int pageSize = 0 ;
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if(totalCount > 0){
this.totalCount = totalCount;
//设置总页数
this.setTotalPageCountByRs();
}
}
public int getCurrentPageNo() {
return currentPageNo;
}
public void setCurrentPageNo(int currentPageNo) {
if(currentPageNo > 0){
this.currentPageNo = currentPageNo;
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if(pageSize > 0 ){
this.pageSize = pageSize;
}
}
//设置总页数
public void setTotalPageCountByRs(){
if(this.totalCount % this.pageSize == 0){
this.totalPageCount = this.totalCount / this.pageSize;
}else if(this.totalCount % this.pageSize > 0){
this.totalPageCount = this.totalCount / this.pageSize + 1;
}else{
this.totalPageCount = 0;
}
}
}
3>分页查询SQL语句
select * from 表名 order by createDate desc limit 起始位置,下标以0开始,页面容量;
★总页数=总记录数 / 每页显示记录数
总页数=总记录数 / 每页显示记录数+1
起始记录数:(当前页码-1)× 每页显示的记录数+1;
结束记录数:当前页码 × 每页显示的记录数
4-2:JSP中实现分页
1>确定当前页
//页面容量
int pageSize=2;
//当前页面
String pageIndex=request.getParameter("pageIndex");
int currentPageNo = 1;;
if(pageIndex == null){
currentPageNo =1;
}else{
try{
currentPageNo = Integer.parseInt(pageIndex);
}catch(NumberFormatException e){
response.sendRedirect("error.jsp");
}
}
//总记录数
int totalCount=newsService.getNewsCount();
//总页数
PageSupport pageSupport = new PageSupport();
pageSupport.setPageSize(pageSize);
pageSupport.setCurrentPageNo(currentPageNo);
pageSupport.setTotalCount(totalCount);
int totalPageCount =pageSupport.getTotalPageCount();
2>页面分页设置
<%--
<%if(currentPageNo > 1){ %>
<a href="newsDetailList.jsp?pageIndex=1">首页</a>
<a href="newsDetailList.jsp?pageIndex=<%=currentPageNo-1%>">上一页</a>
<%}if(currentPageNo < totalPageCount) {%>
<a href="newsDetailList.jsp?pageIndex=<%=currentPageNo+1%>">下一页</a>
<a href="newsDetailList.jsp?pageIndex=<%=totalPageCount %>">尾页</a>
<%} %>
--%>
<%if(currentPageNo > 1){ %>
<a href="javaScript:page_nav(document.forms[0],1)">首页</a>
<a href="javaScript:page_nav(document.forms[0],<%=currentPageNo-1%>)">上一页</a>
<%}if(currentPageNo < totalPageCount) {%>
<a href="javaScript:page_nav(document.forms[0],<%=currentPageNo+1%>)">下一页</a>
<a href="javaScript:page_nav(document.forms[0],<%=totalPageCount %>)">尾页</a>
<%} %>
3>首页和尾页异常处理
//首尾页的异常控制
if(currentPageNo <1){
currentPageNo = 1;
}
if(currentPageNo > totalPageCount){
currentPageNo = totalPageCount;
}
四、EL和JSTL
1、EL语法
1-1:EL表达式:${EL表达式 }
1-2:EL操作符
1>操作符“.”:获取对象的属性
2>操作符“[]”:获取对象的属性、获取集合中的对象
★使用EL表达式之前,要先把变量放在作用域中
1-3:运算符(和java类似)
empty:用于检测变量名是否为空,是否等于null
1-4:EL功能
1>获取JavaBean对象的属性
2>获取数组、List、Map类型对象的元素
3>使用运算符进行数据处理
4>屏蔽一些常见的异常
5>自动实现类型转换
1-5:EL访问作用域
1>pageScope:页面作用域→获取页面范围内的属性值
2>requestScope:请求作用域→获取请求范围内的属性值
3>sessionScope:会话作用域→获取会话范围内的属性值
4>applicationScope:应用程序作用域→获取应用程序范围内的属性值
2、JSTL:JSP标准标签库、实现JSP页面中的逻辑控制
2-1:JSTL使用步骤
1>添加jar包(jstl.jar和standard.jar)
2>在JSP页面添加指令:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2-2:输出标签:用来显示数据
1><c:out>
语法:<c:out value="输出显示的表达式" default="默认输出显示的值" escapeXml="是否对输出的内容进行转义" />
2><c:set>
设置变量的语法:<c:set value="变量的值" var="变量的名称" scope="变量存在的作用范围">
设置对象属性的语法:<c:set value="变量的值" target="对象的名称" property="对象的属性名称" />
3><c:remove>
语法:<c:remove var="变量的名称" scope="变量存在的作用域范围" />
2-3:迭代标签<c:forEach>:可替换for循环语句
语法:<c:foreach var="集合中元素的名称" items="集合对象" varStatus="当前循环的状态信息">
2-3:条件标签<c:if/>:可替代if语句
语法:<c:if test="判断的条件" var="判断的结果" scope="判断结果存放的作用域">
2-4:超链接标签<c:url/>
语法:<c:url value="url">
2-5:超链接的参数标签<c:param>
语法:<c:param name="参数名称" value="参数的值">
2-6:导入标签<c:import/>
语法:<c:import url="URL">
2-7:格式化日期标签<fmt:formatDate/>
语法:<fmt:formatDate value="时间对象" pattern="显示格式"/>
五、Servlet、过滤器、监听器
1、Servlet:接受请求,调用JavaBean去处理请求
1-1:Servlet API:
1>Servlet接口:Java Servlet的基础接口,定义了Servlet必须实现的方法
2>GenericServlet类:继承自Servlet接口,属于通用的,不依赖于协议的Servlet
3>HttpServlet类:继承自GenericServlet类,是在其基础上扩展了HTTP协议的Servlet
4>HttpServletRequest接口:继承自ServletRequest接口,用于获取请求数据的读取
5>HttpServletResponse接口:继承自ServletResponse接口,用于返回响应数据
1-2:创建Servlet
1>实现Servlet接口
2>继承GenericServlet类
3>继承HttpServlet类
1-3:Servlet中主要方法
1>init():Servlet的初始化方法,仅仅会执行一次
2>service():处理请求和生产响应
3>destroy():在服务器停止并且程序中的Servlet对象不再使用的时候调用,只执行一次
4>ServletRequest:封装客户的请求信息,作用相当于JSP内置对象request
5>ServletResponse:创建响应信息,将处理结果返回给客户端,作用相当于JSP内置对象response
6>ServletConfig:包含了servlet的初始化参数信息
1-4:Servlet生命周期
1>加载和实例化:创建Servlet的实例
2>初始化:调用init()方法
3>处理请求:调用servlet()方法
4>销毁:调用destroy()方法
1-5:Servlet的部署:修改web.xml
<servlet>
<servlet-name>servlet</servlet-name> 类名
<servlet-class>cn.web.servlet.Servlet</servlet-class> 包名+类名
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name> 类名
<url-pattern>/servlet</url-pattern> <span style="font-family: Arial, Helvetica, sans-serif;">URL路径</span>
</servlet-mapping>
2、过滤器(Filter):接口
2-1:过滤器的生命周期
1>实例化
2>初始化:调用init()方法
3>执行过滤:调用doFilter()方法
4>销毁:调用destory()方法
2-2:使用过滤器的步骤
1>创建实现Filter接口的类
2>在doFilter()中编写实现过滤的方法
3>调用下一个过滤器或者web资源
4>在web.xml文件中配置过滤器
<filter>
<filter-name>过滤器名</filter-name>
<filter-class>过滤器的完全限定名</filter-class>
</filter>
<filter-mapping>
<filter-name>过滤器名</filter-name>
<url-pattern>过滤器映射的web资源</url-pattern>
</filter-mapping>
2-3:应用场景
1>对请求和响应进行统一处理
2>对请求进行日志记录和审核
3>对数据进行屏蔽和替换(上传代码时去掉空格,压缩代码)
4>对数据进行加密和解密(认证)
六、监听器:web.xml配置(<listener><listener-class>监听器所属类的完全限定名</listener-class> </listener>)
1、HttpSessionBindingListener监听(一对一)
1-1:创建用户类实现HttpSessionBindingListener接口
1-2:在valueBound()方法、valueUnbound()方法实现用户统计数量
1-3:在web.xml中进行监听配置
2、HttpSessionListener监听(设置一次就可以监听所有的session)
方法:1>sessionCreated(HttpSessionEvent event)
2>sessionDestroyed(HttpSessionEvent event)
执行session.invalidate()方法、session会话超时
在web.xml配置监听器
3、ServletContextListener监听:启动服务时获取数据源(所有用户公用一个对象《application》)
contextInitialized、contextDestroyed
★ServletContextListener:在Servlet上下文对象初始化或者销毁时得到通知
ServletContextAttributeListener:在Servlet上下文中的属性列表发生变化时得到通知
HttpSessionListener:在Session创建后或者失效前得到通知
HttpSessionActivationListener:实现该接口的对象,如果绑定到Session中,当Session被钝化或者激活时,Servlet容器将通知该对象
在web.xml配置监听器