jsp進階教程和Servlet
在看此教程之前請先去jsp基礎部分看基礎教程
目錄
1、JavaBean
2、jsp自定義標籤
3、jstl
4、Servlet
5、過濾器
6、監聽器
7、jsp+servlet連線資料庫
8、jsp+servlet分頁
9、jsp+servlet檔案上傳
1、JavaBean
1.1什麼是JavaBean
JavaBean是一種用Java語言寫的可重用元件,可以被Applet、Servlet、JSP進行呼叫,也可以被視覺化開發工具呼叫,包含屬性、方法、事件。
建立JavaBean的要求
①屬性必須私有化
②提供無參建構函式
③私有化的屬性的方法修飾符要為public給其他程式方便訪問,方法命名遵循規範
1.2、第一個JavaBean
JavaBean的屬性可以是任意並且多個型別、 需要對JavaBean提供get(取值)set(設定)方法方便外界訪問。
public class UserBean {
//屬性
private Integer id;
private String name;
private String pwd;
//構造方法
public UserBean(Integer id, String name, String pwd) {
super();
this.id = id;
this.name = name;
this.pwd = pwd;
}
public UserBean() {
super();
// TODO Auto-generated constructor stub
}
//get、set方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
1.3、在jsp頁面使用JavaBean
JSP提供三個關於JavaBean的元件的動作元素,分別是:
①<jsp:useBean>:查詢、或者例項化一個Bean。
語法
id表示JavaBean的名稱,class指的是類的全限定名,scope指的是改Bean的作用域範圍預設為page,可以設定為request、session、application。
②<jsp:setProperty>:設定JavaBean的屬性。
語法
name 表示JavaBean的名稱 property表示JavaBean例項物件的屬性名稱,value表示屬性的值,param表示將JavaBean的某個屬性值設定為請求引數值,會自動轉換成要設定的JavaBean屬性的型別。
③<jsp:getProperty>:獲得Bean的屬性。
例項
<%@page import="java.util.Enumeration" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="enoor.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<!-- id表示JavaBean的名稱 class:JavaBean的路徑 scope:JavanBean的作用範圍 -->
<jsp:useBean id="User" class="com.zhou.UserBean" scope="request" />
<!-- 設定值 -->
<!-- peoperty:JavaBean物件的屬性名 name:JavaBean的id名稱 value:JavaBean物件屬性的值 -->
<jsp:setProperty property="id" name="User" value="1001"/>
<jsp:setProperty property="name" name="User" value="張三"/>
<jsp:setProperty property="pwd" name="User" value="666666"/>
<!-- 使用請求引數設定值 接收引數名為names的值 再將值賦值給name 如果 property="*" 代表賦值給所有屬性名字-->
<jsp:setProperty property="name" name="User" param="names"/>
<form action="">
<input type="text" name="names" />
<input type="submit" value="確定"/>
</form>
<!-- 取值 property="JavaBean物件的屬性名" name="JavaBean物件的id"-->
<table border="1">
<tr>
<th>id</th>
<th>姓名</th>
<th>密碼</th>
</tr>
<tr>
<td><jsp:getProperty property="id" name="User"/></td>
<td><jsp:getProperty property="name" name="User"/></td>
<td><jsp:getProperty property="pwd" name="User"/></td>
</tr>
</table>
</body>
</html>
執行結果
2、jsp自定義標籤
jsp自定義標籤就是使用者自己去定義標籤,當jsp頁面包含標籤會被轉換為servlet,然後servlet執行時web容器會去呼叫相對應標籤的操作。
2.1、怎麼定義jsp自定義標籤
①繼承SimpleTagSupport類。
②重寫的doTag()方法。
package com.zhou;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//繼承SimpleTag
public class hello extends SimpleTagSupport{
//重寫doTag方法
public void doTag() throws JspException, IOException {
//獲得JspContext物件
//將out.println("這是一個自定義標籤!"); 傳遞給JspWrite
JspWriter out = getJspContext().getOut();
out.println("這是一個自定義標籤!");
}
}
③在WEB-INF下面建立標籤庫描述檔案
<!-- 建立以.tld結尾的標籤庫檔案 -->
<!-- 定義標籤庫 -->
<taglib>
<!-- 標籤庫的版本 -->
<tlib-version>1.0</tlib-version>
<!-- 依賴的JSP版本 -->
<jsp-version>2.0</jsp-version>
<!-- 當在JSP中使用標籤時,此標籤庫首選或者建議的字首 -->
<short-name>Example TLD</short-name>
<!-- 定義標籤 -->
<tag>
<!-- 標籤的名字 -->
<name>hello</name>
<!-- Java標籤處理器類的名稱 -->
<tag-class>com.zhou.hello</tag-class>
<!-- 標籤主體部分的內容 -->
<body-content>empty</body-content>
</tag>
</taglib>
④在jsp頁面使用標籤
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="enoor.jsp" %>
<!-- 使用自定義的標籤 prefix:標籤的字首 uri:標籤的路徑 -->
<%@ taglib prefix="dd" uri="/WEB-INF/custom.tld" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<!-- 建立了一個標籤名為hello的標籤並且字首為dd -->
<dd:hello/>
</body>
</html>
執行結果
2.2、自定義標籤自定義內容
package com.zhou;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//繼承SimpleTag
public class hello extends SimpleTagSupport{
//定義一個StringWriter物件
StringWriter sw = new StringWriter();
//重寫doTag方法
public void doTag() throws JspException, IOException {
//想要輸出的資訊作為標籤體的內容輸出
getJspBody().invoke(sw);
//呼叫JspWriter將標籤體的內容輸出到瀏覽器
getJspContext().getOut().println(sw.toString());
}
}
<!-- 建立以.tld結尾的標籤庫檔案 -->
<!-- 定義標籤庫 -->
<taglib>
<!-- 標籤庫的版本 -->
<tlib-version>1.0</tlib-version>
<!-- 依賴的JSP版本 -->
<jsp-version>2.0</jsp-version>
<!-- 當在JSP中使用標籤時,此標籤庫首選或者建議的字首 -->
<short-name>Example TLD</short-name>
<!-- 定義標籤 -->
<tag>
<!-- 標籤的名字 -->
<name>hello</name>
<!-- Java標籤處理器類的名稱 -->
<tag-class>com.zhou.hello</tag-class>
<!-- 標籤主體部分的內容 -->
<!-- 可以接受文字,EL表示式,和JSP的動作。 -->
<body-content>scriptless</body-content>
</tag>
</taglib>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="enoor.jsp" %>
<!-- 使用自定義的標籤 prefix:標籤的字首 uri:標籤的路徑 -->
<%@ taglib prefix="dd" uri="/WEB-INF/custom.tld" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<!-- 建立了一個標籤名為hello的標籤並且字首為dd -->
<dd:hello>2132131</dd:hello>
</body>
</html>
結果:2312131
2.3、建立帶屬性的自定義標籤
package com.zhou;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;
//繼承SimpleTag
public class hello extends SimpleTagSupport{
//定義一個變數
private String msg;
//set方法
public void setMsg(String msg) {
this.msg = msg;
}
//定義一個StringWriter物件
StringWriter sw = new StringWriter();
//重寫doTag方法
public void doTag() throws JspException, IOException {
//如果屬性不為空呼叫JspWriter將標籤體的內容輸出到瀏覽器
if(msg!=null) {
JspWriter out = getJspContext().getOut();
out.println( msg );
}else {
//想要輸出的資訊作為標籤體的內容輸出
getJspBody().invoke(sw);
//呼叫JspWriter將標籤體的內容輸出到瀏覽器
getJspContext().getOut().println(sw.toString());
}
}
}
<!-- 建立以.tld結尾的標籤庫檔案 -->
<!-- 定義標籤庫 -->
<taglib>
<!-- 標籤庫的版本 -->
<tlib-version>1.0</tlib-version>
<!-- 依賴的JSP版本 -->
<jsp-version>2.0</jsp-version>
<!-- 當在JSP中使用標籤時,此標籤庫首選或者建議的字首 -->
<short-name>Example TLD</short-name>
<!-- 定義標籤 -->
<tag>
<!-- 標籤的名字 -->
<name>hello</name>
<!-- Java標籤處理器類的名稱 -->
<tag-class>com.zhou.hello</tag-class>
<!-- 標籤主體部分的內容 -->
<!-- 可以接受文字,EL表示式,和JSP的動作。 -->
<body-content>scriptless</body-content>
<!-- 義多個,定義Tag的屬性 -->
<attribute>
<!-- 屬性的名字 -->
<name>msg</name>
</attribute>
</tag>
</taglib>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="enoor.jsp" %>
<!-- 使用自定義的標籤 prefix:標籤的字首 uri:標籤的路徑 -->
<%@ taglib prefix="dd" uri="/WEB-INF/custom.tld" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<!-- 建立了一個標籤名為hello的標籤並且字首為dd -->
<dd:hello msg="你好啊"/>
</body>
</html>
執行結果:你好啊!
我這裡只講解一下c標籤一些用法
詳情參照:https://www.runoob.com/jsp/jsp-jstl.html
3.2、jstl優點
JSTL的優點如下:
1、簡化了JSP和Web應用程式的開發。
2、在應用程式伺服器之間提供了一致的介面,最大限度地提高了·Web應用在各應用伺服器之間的移植。
3、允許JSP設計工具與Web應用程式開發的進一步整合。
4、以一種統一的方式減少了JSP中的Scriptlets程式碼數量,可以達到程式中沒有任何Scriptlest程式碼。
⑤JSTL封裝了JSP開發中的常用功能,提高開發的效率
3.3、使用方法
①要在JSP頁面中使用JSTL標籤,需使用taglib指令引用標籤庫
②點選這裡下載需要的jar包
3.4、常用的核心標籤
3.4.1、c:if標籤
<c:if>標籤判斷表示式的值,如果表示式的值為 true 則執行其主體內容。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引用標籤庫 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 設定一個變數 跟其對應的作用域 以及值 -->
<c:set var="i" scope="request" value="20"></c:set>
<!-- 進行判斷 -->
<c:if test="${i>19}">
true
</c:if>
</body>
</html>
結果為:true
3.4.2、c:forEach標籤
c:forEach標籤的一些屬性
items :要被迴圈的資訊。
begin :開始的元素。
end :最後一個元素。
step :每一次迭代的步長 。
var :代表當前條目的變數名稱 。
varStatus :代表迴圈狀態的變數名稱。
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引用標籤庫 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- var="變數名" begin="開始" end="結束" step="迭代增量" -->
<c:forEach var="i" begin="1" end="5" step="2">
<c:out value="${i}" />
</c:forEach>
</body>
</html>
執行結果:1 3 5
3.4.3、<c:choose>, <c:when>, <c:otherwise> 標籤
<c:choose>標籤與Java switch語句的功能一樣,<c:choose>標籤中對應有<c:when>代表首位switch的case,switch語句中有default,而<c:choose>標籤中有<c:otherwise>。
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引用標籤庫 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:set var="money" value="2999"></c:set>
<c:choose>
<c:when test="${money>=3000}">錢夠了</c:when>
<c:otherwise>錢少了</c:otherwise>
</c:choose>
</body>
</html>
執行結果:錢少了
4、Servlet
4.1、Servlet簡介
Servlet(Server Applet)是Java Servlet的簡稱,是用Java編寫的伺服器端程式,主要功能在於互動式地瀏覽和生成資料,生成動態Web內容。
4.2、Servlet工作原理
1.瀏覽器向伺服器發出GET請求
2.伺服器上的Tomcat接收到該url,根據該url判斷為Servlet請求,此時Tomcat將產生兩個物件:請求物件(HttpServletRequest)和響應物件(HttpServletResponce)
3.Tomcat根據url找到目標Servlet,且建立一個執行緒
4.Tomcat將剛才建立的請求物件和響應物件傳遞給該執行緒
5.Tomcat呼叫Servlet的service()方法
6.service()方法根據請求型別(本示例為GET請求)呼叫doGet()(本示例呼叫doGet())或doPost()方法
7.doGet()執行完後,將結果返回給Tomcat
8.執行緒被銷燬或被放線上程池中
4.3、Servlet生命週期
關於Servlet的生命週期主要有三個方法
①init初始化方法:當客戶端傳送的時候會呼叫init方法建立servlet,通過ServletConfig進行初始化,只建立一次下次請求不建立。
②service處理客戶端請求方法:當servlet建立完成的時候,將客戶端的請求交給service處理,並返回給客戶端。
每當收到客戶端的請求,伺服器會產生一個新的執行緒進行服務,根據請求的型別,呼叫其對應處理的方法。
③destroy銷燬方法:當web應用被終止,或者Servlet容器終止執行,或者Servlet重新裝載Servlet新例項時,Servlet容器會呼叫Servlet的destroy()方法。
下面來模擬一下servlet的生命週期
首先建立一個類繼承HttpServlet並重寫inti()、service()、destroy()方法。
package Servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class MyServlet extends HttpServlet{
public MyServlet() {
System.out.println("開始建立Servlet....");
}
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("Servlet開始初始化....");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("Servlet開始工作....");
}
@Override
public void destroy() {
System.out.println("Servlet開始銷燬....");
}
}
servlet2.5版本需要手動在webxml配置servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>JSP</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置servlet -->
<servlet>
<!-- servlet的名字 -->
<servlet-name>servlet</servlet-name>
<!-- servlet的類全限定名 -->
<servlet-class>Servlet.MyServlet</servlet-class>
</servlet>
<!-- 配置servlet的對映 -->
<servlet-mapping>
<!-- servlet的內部名稱要和上面的名稱一樣 -->
<servlet-name>servlet</servlet-name>
<!-- servlet的請求路徑 -->
<!-- 使用http://localhost:8888/JSP/index.jsp/myservlet即可訪問servlet -->
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
</web-app>
servlet3.0版本可以直接在類上使用@WebServlet("/")註解
@WebServlet("/myservlet")
當停止tomcat伺服器servlet開始進行銷燬
4.4、表單提交到Servlet
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引用標籤庫 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--action="servlet url" -->
<form action="myservlet">
姓名:<input type="text" name="username"/>
<br/>
密碼:<input type="text" name="password"/>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
package Servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/myservlet")
public class MyServlet extends HttpServlet{
//form表單預設提交方式是get所以重寫doget方法
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//根據表單input的name值獲取資料
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("姓名:"+username);
System.out.println("密碼:"+password);
}
}
輸出結果
get請求引數會明文顯示,隱私資料建議使用post方式提交較為安全
姓名:張三
密碼:666
4.5、解決頁面亂碼問題
使用post方式請求
request.setCharacterEncoding("UTF-8");
使用get方式請求
parameter=new String(parameter.getbytes("iso8859-1"),"utf-8");
列印資料在web頁面
response.setContentType("text/html;charset=utf-8");
4.6、請求轉發和重定向
請求轉發
request.getRequestDispatcher(URL地址).forward(request, response);
客戶端請求servlet,servlet處理後呼叫forward方法將資料轉發到另外一個頁面。
重定向
response.sendRedirect(URL地址);
客戶端請求servlet,servlet處理後使用response呼叫sendRedirect方法把要訪問的目標資源作為response響應頭資訊發給客戶端瀏覽器,不攜帶資料的情況下使用重定向比較好。
例項
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引用標籤庫 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="myservlet" method="post">
姓名:<input type="text" name="username"/>
<br/>
密碼:<input type="text" name="password"/>
<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
package Servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/myservlet")
public class MyServlet extends HttpServlet{
//form表單預設提交方式是get所以重寫doget方法
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理亂碼問題
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//根據表單input的name值獲取資料
String username = request.getParameter("username");
String password = request.getParameter("password");
//如果賬號密碼正確轉發到success.jsp介面
if(username.equals("zs")&&password.equals("123")) {
//包username儲存到request域
request.setAttribute("name", username);
request.getRequestDispatcher("success.jsp").forward(request, response);
}else {
//否則跳轉到index.jsp介面
response.sendRedirect("index.jsp");
}
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
歡迎您:${name}
</body>
</html>
執行結果
5、過濾器(Filter)
5.1、什麼是過濾器
過濾器(Filter)是Servlet常用的一種技術,可以對web資源進行攔截:(例如Jsp, Servlet, 靜態圖片檔案或靜態 html 檔案),對攔截的資源進行一個許可權控制。
Servlet API提供了一個介面Fileter 所有實現介面的類稱之為過濾器。
5.2、過濾器原理
Filter介面提供了三個方法:inti()初始化過濾器、doFilter(執行過濾),destory(銷燬過濾器)。
①客戶端(瀏覽器)傳送請求。
②服務端呼叫init方法建立請求(request)、響應物件(response)。
③每一個過濾器都有請求響應物件。
④呼叫doFilter()方法執行過濾,只有當過濾器放行後才能訪問Servlet。
⑤最後返回給客戶端。
用法:
①建立類Filter介面。
②實現Filter介面的方法。
③xml配置過濾器也可以通過在類上面加註解。
例項
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="success.jsp">訪問</a>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>jsp</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置過濾器 -->
<filter>
<!-- 過濾器名字 -->
<filter-name>myfilter</filter-name>
<!-- 過濾器的實現類 -->
<filter-class>Filter.MyFilter</filter-class>
</filter>
<!-- 配置過濾器對映(規則) -->
<filter-mapping>
<!-- 這裡的filter-name要上面的一致 -->
<filter-name>myfilter</filter-name>
<!-- 過濾所有的資源 -->
<url-pattern>/success.jsp</url-pattern>
</filter-mapping>
</web-app>
package Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyFilter implements Filter{
public MyFilter() {
System.out.println("建立過濾器....");
}
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("過濾器初始化....");
}
public void destroy() {
System.out.println("過濾器開始銷燬...");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("過濾器開始執行....");
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'success.jsp' starting page</title>
</head>
<body>
歡迎你!!!
</body>
</html>
以上程式碼實現了資源攔截,當index.jsp頁面想訪問success.jsp頁面的時候,被過濾器攔截了。
沒有列印"歡迎你"說明攔截成功!
當停止tomcat伺服器的時候過濾器會進行銷燬。
5.3、過濾器實現登入攔截
登入介面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登入</title>
</head>
<body>
<form action="loginServlet" method="post">
使用者名稱:<input type="text" name="username"/>
<br/>
密碼:<input type="password" name="password"/>
<br/>
<input type="submit" value="確定"/>
<a href="MyJsp.jsp">跳轉</a>
</form>
</body>
</html>
登入成功介面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'success.jsp' starting page</title>
</head>
<body>
歡迎您:${name}
</body>
</html>
登入的servlet
package Login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MyLogin extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決亂碼問題
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//獲取請求引數
String name = request.getParameter("username");
String pwd = request.getParameter("password");
HttpSession session = request.getSession();
//如果登入成功就設定一個session
if(name.equals("zs") && pwd.equals("123")) {
session.setAttribute("name", name);
request.getRequestDispatcher("success.jsp").forward(request, response);
}else {
//登入失敗就重定向到登入介面
response.sendRedirect("login.jsp");
}
}
}
登入過濾器
package Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MyFilter implements Filter{
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain fChain)
throws IOException, ServletException {
HttpServletRequest req =(HttpServletRequest) request;
HttpServletResponse rep = (HttpServletResponse)response;
//獲得請求路徑
String uri = req.getRequestURI();
boolean flag =true;
//如果請求路徑不是從login.jsp並且session名字為name的值為null就不放行
if(uri.indexOf("login")==-1 &&req.getSession().getAttribute("name")==null) {
flag=false;
}
if(flag) {
fChain.doFilter(request, response);
}else {
rep.sendRedirect("login.jsp");
}
}
public void init(FilterConfig arg0) throws ServletException {
}
}
註解註冊過濾器
//攔截所有資源
@WebFilter(urlPatterns= {"/*"})
web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 歡迎頁 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--登入Servlet-->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>Login.MyLogin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
<!-- 配置過濾器 -->
<filter>
<!-- 過濾器名字 -->
<filter-name>myfilter</filter-name>
<!-- 過濾器對應類全限定名 -->
<filter-class>Filter.MyFilter</filter-class>
</filter>
<!-- 配置過濾器對映 -->
<filter-mapping>
<!-- 這裡的filter-name要上面的一致 -->
<filter-name>myfilter</filter-name>
<!-- 過濾所有的資源 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
5.4、編碼過濾器
當進行提交或者列印內容到頁面上的時候會出現中文亂碼現象,按照以往的方式我們會寫:
①解決頁面亂碼
response.setHeader("content-type", "text/html;charset=UTF-8");
②解決post請求亂碼
response.setCharacterEncoding("UTF-8");
③get請求亂碼
String username=request.getParameter("username");
username=new String(username.getBytes("iso8859-1"),"UTF-8");
以上三種解決亂碼的方式每當我們建立一個Servlet的時候就要寫一遍,不實用,通過下面的編碼過濾器將編碼統一設定為utf-8無論建立多少個servlet都能解決中文亂碼問題。
例項
index.jsp介面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="#" method="post">
姓名<input type="text" name="name">
<br>
<input type="submit" value="提交">
</form>
<%
String name = request.getParameter("name");
response.getWriter().print(name);
%>
</body>
</html>
編碼過濾器類
package Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EncodingFilter implements Filter{
public void destroy() {
// TODO Auto-generated method stub
}
private String encoding = null;
private FilterConfig config;
public void init(FilterConfig filterConfig) throws ServletException {
this.config=filterConfig;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
//如果encoding為null,則採用FilterConfig的config物件讀取編碼,encoding編碼在配置檔案web.xml中定義
if(encoding==null) {
encoding=config.getInitParameter("encoding");
}
//如果不為null通過request物件將編碼設定為encoding的值
//並且通過response物件設定頁面的型別和字元編碼
if(encoding!=null) {
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset="+encoding);
}
//放行
chain.doFilter(request, response);
}
}
註解配置註冊編碼過濾器
@WebFilter(urlPatterns= {"/*"},initParams= {@WebInitParam(name="encoding",value="UTF-8")})
web.xml配置編碼過濾器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 歡迎頁 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置編碼過濾器 -->
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>Filter.EncodingFilter</filter-class>
<!-- 初始化引數 -->
<init-param>
<!-- 引數名 -->
<param-name>encoding</param-name>
<!-- 引數值 -->
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 配置編碼過濾器對映 -->
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
6、監聽器(Listener)
6.1、監聽器概念
監聽器是主要用於監聽ServletContext、HttpSession和ServletRequest等域物件的建立和銷燬事件,它還可以監聽域物件的屬性發生修改的事件,可以在事件發生前或者發生後做一些必要的處理。
6.2、監聽器工作原理
簡單解釋就是當被監聽者的某一個條件被觸發了,通知監聽者該要幹嘛。
在java中可以理解為介面回撥:
6.3、監聽器的分類
jsp中的監聽器分為三類:ServletContext事件監聽器、HttpSession事件監聽器、ServletRequest事件監聽器。
6.4、監聽ServletContext事件
6.4.1、監聽ServletContextListener建立與銷燬
常用方法
方法名 | 觸發條件 |
---|---|
public void contextInitialized(ServletContextEvent sce) | 建立Servletcontext(即建立應用程式)時 |
public void contextDestroyed(ServletContextEvent sce) | 銷燬Servletcontext(停止應用程式) |
web.xml註冊上下文監聽器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 歡迎頁 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置監聽器 -->
<listener>
<listener-class>Listene.ListeneDemo1</listener-class>
</listener>
<!-- 配置上下文初始化引數名和值 -->
<context-param>
<param-name>name</param-name>
<param-value>imooc</param-value>
</context-param>
</web-app>
上下文監聽器類
package Listene;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//監聽請求物件、響應物件的建立和銷燬
public class ListeneDemo1 implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) {
//獲得上下文初始化引數
String name = sce.getServletContext().getInitParameter("name");
System.out.println("Servler上下文:"+name+"建立了......");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Servlet上下文銷燬了........");
}
}
執行結果
當啟動web容器
停止web容器
6.4.2、監聽ServletContextAttributeListener屬性的增、刪改
public void attributeAdded(ServletContextAttributeEvent arg); | 增加屬性 |
---|---|
public void attributeRemoved(ServletContextAttributeEvent scab); | 屬性刪除 |
public voidattributeRepalced(ServletContextAttributeEvent arg); | 屬性替換(第二次設定同一屬性) |
例項
建立監聽器實現ServletContextAttributeListener介面的三個方法
這裡使用的是註解方式註冊監聽器
package Listene;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
//監聽請求物件、響應物件的建立和銷燬
@WebListener("/ls")
public class ListeneDemo1 implements ServletContextAttributeListener{
public void attributeAdded(ServletContextAttributeEvent scab) {
System.out.println("新增了名為:"+scab.getName()+"值為:"+scab.getValue()+"的屬性" );
}
public void attributeRemoved(ServletContextAttributeEvent scab) {
System.out.println("刪除了名為:"+scab.getName()+"值為:"+scab.getValue()+"的屬性....");
}
public void attributeReplaced(ServletContextAttributeEvent scab) {
System.out.println("替換了名為:"+scab.getName()+"值為:"+scab.getValue()+"的屬性");
}
}
建立servlet
package Listene;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/jsp/ss")
public class sss extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//建立全域性物件
ServletContext servletContext = getServletContext();
//新增
servletContext.setAttribute("name","張三");
//覆蓋
servletContext.setAttribute("name", "李四");
//刪除
servletContext.removeAttribute("name");
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="jsp/ss">訪問</a>
</body>
</html>
當點選超連結訪問Servlet的時候控制檯列印如下資訊
新增了名為:org.apache.jasper.runtime.JspApplicationContextImpl值為:org.apache.jasper.runtime.JspApplicationContextImpl@11551222的屬性
新增了名為:org.apache.jasper.compiler.ELInterpreter值為:org.apache.jasper.compiler.ELInterpreterFactory$DefaultELInterpreter@615885d1的屬性
新增了名為:name值為:張三的屬性
替換了名為:name值為:張三的屬性
刪除了名為:name值為:李四的屬性....
說明監聽成功
6.5、監聽ServletRequest事件
6.5.1、ServletRequestListener
ServletRequestListener常用方法
方法名 | 觸發條件 |
---|---|
public void requestInitialized(ServletRequestEvent sre) | 建立request時 |
public void requestDestroyed(ServletRequestEvent sre) | 銷燬request時 |
package Listene;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
//監聽請求物件建立和銷燬
@WebListener("/ls")
public class ListeneDemo implements ServletRequestListener{
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("request物件銷燬了.....");
}
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("request物件建立了.....");
}
}
當客戶端通過http協議訪問伺服器的時候ServletRequest開始進行建立並銷燬(因為ServletRequest只在第一次請求有效)。
執行結果
request物件建立了.....
request物件銷燬了.....
6.5.2、監聽ServletRequestAttributeListener屬性增刪改
ServletRequestAttributeListener常用方法
方法名 | 觸發條件 |
---|---|
public void attributeAdded(ServletRequestAttributeEvent srae) | 新增屬性時 |
public void attributeReplaced(ServletRequestAttributeEvent srae) | 替換屬性時 |
public void attributeRemoved(ServletRequestAttributeEvent srae) | 移除屬性時 |
public String getName(); | 得到屬性名稱 |
public Object getValue(); | 取得屬性的值 |
例項
package Listene;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
//監聽請求物件建立和銷燬
@WebListener("/ls")
public class ServletRquestListeners implements ServletRequestAttributeListener
{
public void attributeAdded(ServletRequestAttributeEvent arg0) {
System.out.println("增加了" + arg0.getName() + " " +
arg0.getValue() );
}
public void attributeReplaced(ServletRequestAttributeEvent arg0) {
System.out.println("修改了" + arg0.getName() + " " +
arg0.getValue() );
}
public void attributeRemoved(ServletRequestAttributeEvent arg0) {
System.out.println("去除了" + arg0.getName() + " " +
arg0.getValue() );
}
}
package Listene;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/jsp/dd")
public class ddd extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("name", "張三");
req.setAttribute("name", "李四");
req.removeAttribute("name");
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="jsp/dd">訪問</a>
</body>
</html>
結果
修改了org.apache.catalina.ASYNC_SUPPORTED true
增加了name 張三
修改了name 張三
去除了name 李四
6.6、監聽會話(HttpSession)事件
6.6.1、監聽HttpSessionListener
常用方法
方法名 | 觸發條件 |
---|---|
public void sessionCreated(HttpSessionEvent se) | 建立session時 |
public void sessionDestroyed(HttpSessionEvent se) | 銷燬session時 |
例項
index.jsp頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
request.getSession().setAttribute("name", "zs");
%>
<a href="qc.jsp">清除session</a>
</body>
</html>
監聽器頁面
package com.zhou;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class Listener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent se) {
System.out.println("建立了sessison........");
}
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("銷燬了session..........");
}
}
web.xml配置介面
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>jsp</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>com.zhou.Listener</listener-class>
</listener>
</web-app>
以上程式碼我們在index.jsp頁面建立了一個session控制檯列印如下資訊:
建立了sessison........
當點選連結清除session的時候控制檯列印如下資訊說明session被清除成功
銷燬了session..........
6.6.2、監聽HttpSessionAttributeListener
常用方法
方法名 | 觸發條件 |
---|---|
public void attributeAdded(HttpSessionBindingEvent event) | 新增屬性時 |
public void attributeReplaced(HttpSessionBindingEvent event) | 替換屬性時 |
public void attributeRemoved(HttpSessionBindingEvent event) | 移除屬性時 |
例項
index.jsp介面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<%
//增加
request.getSession().setAttribute("name", "zs");
//替換
request.getSession().setAttribute("name", "ls");
%>
<!--清除 -->
<a href="qc.jsp">清除session</a>
</body>
</html>
監聽器介面採用的是註解註冊
package com.zhou;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
@WebListener
public class Listener implements HttpSessionAttributeListener{
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("新增了"+se.getName()+"屬性");
}
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("刪除了"+se.getName()+"屬性");
}
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("替換了"+se.getName()+"屬性");
}
}
清除session介面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%request.getSession().invalidate(); %>
</body>
</html>
以上程式碼當我們開啟瀏覽器的時候訪問伺服器會顯示
新增了name屬性
替換了name屬性
當點選了清除session連結所有session失效從而也達到刪除session的目的,當然也可以通過“request.removeAttribute(“session名字”);”刪除指定seession 或者等待session名字到期即可
7、jsp+servlet連線資料庫
7.1、使用mysql驅動包連線資料庫
準備好連線mysql的jar包,我這裡使用的是:mysql-connector-java-5.1.49.jar
建立servlet
package com.zhou;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/findAll")
public class Servlets extends HttpServlet{
private final static String DRIVER="com.mysql.jdbc.Driver";
private final static String URI="jdbc:mysql:///sys?useSSL=false";
private final static String USERNAME="root";
private final static String PASSWORD="19990704";
private static PreparedStatement ps;
private static Connection conn;
private static ResultSet rs;
//載入驅動
static {
try {
Class.forName(DRIVER);
System.out.println("載入驅動成功....");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
resp.setContentType("text/html;charset=utf-8");
//建立連線
conn = DriverManager.getConnection(URI,USERNAME,PASSWORD);
//定義查詢sql語句
String sql = "select * from user";
//執行sql語句
ps = conn.prepareStatement(sql);
//執行查詢
rs =ps.executeQuery();
//遍歷結果集
PrintWriter out = resp.getWriter();
while (rs.next()) {
//將結果列印到頁面
//""裡面的內容要跟資料庫裡面的欄位對應
out.print(rs.getInt("id"));
out.print(" ");
out.print(rs.getString("name"));
out.print(" ");
out.print(rs.getString("password"));
out.println("<br/>");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//釋放資源
try {
if (rs!=null) {
rs.close();
}
if (ps!=null) {
ps.close();
}
if (conn!=null) {
conn.close();
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}
建立jsp頁面用來請求servlet
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="findAll">查詢</a>
</body>
</html>
執行結果
7.2、使用c3p0連線資料庫
C3P0是一個開源的JDBC連線池,它實現了資料來源和JNDI繫結,支援JDBC3規範和JDBC2的標準擴充套件,支援自動回收。目前使用它的開源專案有Hibernate、Spring等。
使用方法
①下載mysql驅動包和c3p0jiar包:mysql-connector-java-5.1.49.jar、c3p0-0.9.1.2.jar。
②在src下編寫c3p-config配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 我們希望在配置檔案中,出現連結的引數資訊 -->
<!-- 1、配置預設資料來源 -->
<default-config>
<!-- name 屬性定義 連結引數的key 標籤的內容 代表值 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 採用了簡寫形式,三個/ -->
<property name="jdbcUrl">jdbc:mysql:///sys?useSSL=false</property>
<property name="user">root</property>
<property name="password">19990704</property>
<!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數 -->
<property name="acquireIncrement">5</property>
<!--初始化時獲取十個連線,取值應在minPoolSize與maxPoolSize之間 -->
<property name="initialPoolSize">10</property>
<!--連線池中保留的最小連線數 -->
<property name="minPoolSize">10</property>
<!--連線池中保留的最大連線數 -->
<property name="maxPoolSize">50</property>
</default-config>
</c3p0-config>
編寫jdbc工具類
package com.zhou;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.PreparedStatement;
public class JdbcUtil {
//建立c3p0的例項,讀取src下面的配置檔案中default-config裡面的預設資料來源
private static ComboPooledDataSource ds = new ComboPooledDataSource();
//建立c3p0的例項,讀取src下面的配置檔案中named-config裡面的初始資料來源
// private static ComboPooledDataSource ds1 = new ComboPooledDataSource("petshop");
//從連線池裡面獲取連線
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//關閉兩個引數,釋放資源
public static void close(Connection conn, PreparedStatement ps) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
//使用連線池後,此時的close()並不是關閉連結,而是把連結放回到了連線池中
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉三個引數,釋放資源
public static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs!=null) {
rs.close();
}
if (ps!=null) {
ps.close();
}
if (conn!=null) {
conn.close();
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
編寫servlet
package com.zhou;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Connection;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/findAll")
public class Servlets extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
resp.setContentType("text/html;charset=utf-8");
//建立連線
conn = JdbcUtil.getConnection();
//定義查詢sql語句
String sql = "select * from user";
//執行sql語句
ps = conn.prepareStatement(sql);
//執行查詢
rs =ps.executeQuery();
//遍歷結果集
PrintWriter out = resp.getWriter();
while (rs.next()) {
//將結果列印到頁面
//""裡面的內容要跟資料庫裡面的欄位對應
out.print(rs.getInt("id"));
out.print(" ");
out.print(rs.getString("name"));
out.print(" ");
out.print(rs.getString("password"));
out.println("<br/>");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//釋放資源
JdbcUtil.close(conn, ps, rs);
}
}
}
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="findAll">查詢</a>
</body>
</html>
執行結果
8、jsp+servlet分頁
8.1、什麼是分頁
當我們開啟百度隨便搜尋一個東西會出現如下紅框框裡面的內容有頁碼,還可以上一頁下一頁,簡而言之就是把從資料庫裡面查詢出來的資料,控制他的每頁資料顯示條數。
8.2、分頁思路
①在servlet定義當前頁,從那條記錄開始分頁,以及每頁顯示的條數。
②判斷前端傳來的當前頁是否為null,不為null就轉整數。
③判斷前端傳來的每頁需要顯示的條數是否為null,不為null就轉整數。
④計算開始頁資訊:(開始頁+每頁顯示條數)*(當前頁-1);
四獲取資料的總條數。
⑤根據總條數計算分頁總數:
如果(總條數/每頁顯示條數!=0)
就向上取整Math.ceil(總條數/pageS每頁顯示條數)+1
否則向上取整Math.ceil(總條數/pageS每頁顯示條數)。
⑥把總條數、分頁總數和當前頁以及集合儲存到request域,然後轉發到前臺jsp頁面。
8.3、使用mysql關鍵字limit實現分頁
語法:select * from 表名 limit 引數1,引數2
引數1代表從第幾頁開始,引數2表示顯示的條數。
例項:select * from user limit 1,2
下面我們去程式碼裡面實現分頁效果
index.jsp介面
需要引入c標籤遍歷後臺集合資料到頁面上(需要jstl jar包)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 引入c 標籤 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<a href="findAll">查詢</a>
<center>
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<th>編號</th>
<th>姓名</th>
<th>密碼</th>
</tr>
<c:forEach items="${user}" var="u">
<tr>
<td>${u.id}</td>
<td>${u.name}</td>
<td>${u.password}</td>
</tr>
</c:forEach>
</table>
當前頁${pageNum}/總頁數${page}
<!-- 當前頁不等於1 代表可以進跳轉到首頁 -->
<c:if test="${pageNum!=1}">
<a href="findAll?pageNum=1">首頁</a>
</c:if>
<!-- 當前頁不等於1 分頁總數代表可以進行上一頁 -->
<c:if test="${pageNum!=1}">
<a href="findAll?pageNum=${pageNum-1}">上一頁</a>
</c:if>
<!-- 當前頁等於1 分頁總數代表不可以進行上一頁 -->
<c:if test="${pageNum==1}">
上一頁
</c:if>
<!-- 當前頁不等於分頁總數代表可以進行下一頁 -->
<c:if test="${pageNum!=page}">
<a href="findAll?pageNum=${pageNum+1}">下一頁</a>
</c:if>
<c:if test="${pageNum==page}">
下一頁
</c:if>
<!-- 當前頁不等於1 代表可以進跳轉到首頁 -->
<c:if test="${pageNum!=page}">
<a href="findAll?pageNum=${page}">尾頁</a>
</c:if>
跳轉到<input type="text" value="" id="count" style="width: 30px">頁
<button onclick="tz()">跳轉</button>
每頁顯示 <input type="text" value="" id="row" style="width: 30px">
條
<button onclick="xs()">顯示</button>
</center>
</body>
<script type="text/javascript">
//跳轉到指定頁函式方法
function tz () {
//獲取輸入框的值
var count=document.getElementById("count").value;
//判斷輸入的數是否是整數
var i =parseInt(count);
if(i!=count||count>${page}){
//輸入的數大於總分頁數提示錯誤資訊
alert("輸入的數有誤請重新輸入!")
count=document.getElementById("count").value="";
}else{
window.location.href="findAll?pageNum="+count;
}
}
//控制顯示條數的函式方法
function xs () {
//獲取輸入框的值
var row=document.getElementById("row").value;
//轉整數
var i =parseInt(row);
//判斷輸入的數是否是整數
if(i!=row){
alert("輸入的數有誤請重新輸入!")
row=document.getElementById("row").value="";
}else if(row>${page}){
//輸入的數大於總條數提示錯誤資訊
alert("輸入的數不能大於總數居條數!")
row=document.getElementById("row").value="";
}else{
//輸入的數是整數把顯示的條數傳到後臺取
window.location.href="findAll?pagesize="+row;
}
}
</script>
</html>
c3p0-config.xml配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 我們希望在配置檔案中,出現連結的引數資訊 -->
<!-- 1、配置預設資料來源 -->
<default-config>
<!-- name 屬性定義 連結引數的key 標籤的內容 代表值 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 採用了簡寫形式,三個/ -->
<property name="jdbcUrl">jdbc:mysql:///sys?useSSL=false</property>
<property name="user">root</property>
<property name="password">19990704</property>
<!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數 -->
<property name="acquireIncrement">5</property>
<!--初始化時獲取十個連線,取值應在minPoolSize與maxPoolSize之間 -->
<property name="initialPoolSize">10</property>
<!--連線池中保留的最小連線數 -->
<property name="minPoolSize">10</property>
<!--連線池中保留的最大連線數 -->
<property name="maxPoolSize">50</property>
</default-config>
</c3p0-config>
jdbcUtil連線資料庫工具類
package com.zhou;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.PreparedStatement;
public class JdbcUtil {
//建立c3p0的例項,讀取src下面的配置檔案中default-config裡面的預設資料來源
private static ComboPooledDataSource ds = new ComboPooledDataSource();
//建立c3p0的例項,讀取src下面的配置檔案中named-config裡面的初始資料來源
// private static ComboPooledDataSource ds1 = new ComboPooledDataSource("petshop");
//從連線池裡面獲取連線
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//關閉兩個引數,釋放資源
public static void close(Connection conn, PreparedStatement ps) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
//使用連線池後,此時的close()並不是關閉連結,而是把連結放回到了連線池中
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//關閉三個引數,釋放資源
public static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs!=null) {
rs.close();
}
if (ps!=null) {
ps.close();
}
if (conn!=null) {
conn.close();
}
} catch (Exception e2) {
// TODO: handle exception
}
}
}
servlet
package com.zhou;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.sql.Connection;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/findAll")
public class Servlets extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決頁面顯示內容亂碼問題
response.setContentType("text/html;charset=utf-8");
//從第幾條資料開始分頁
int pageStart = 0;
//每頁顯示資料的條數
int pageSize = 2;
//設定當前頁
int pageNum = 1;
//獲取從前端傳來的頁碼
String pageNums=request.getParameter("pageNum");
//如果當前頁碼不為空把頁碼轉換為整數賦值給當前頁碼
if(pageNums!=null) {
pageNum=Integer.parseInt(pageNums);
}
//獲取從前端傳來的頁碼
String pageSizes=request.getParameter("pagesize");
//如果當前頁碼不為空把頁碼轉換為整數賦值給當前頁碼
if(pageSizes!=null) {
pageSize=Integer.parseInt(pageSizes);
}
//計算開始頁
pageStart = (pageStart+pageSize)*(pageNum-1);
List<User> list = UserDao.findAll(pageStart,pageSize);
//獲取分頁的總頁數
int size = UserDao.Selectsize();
request.setAttribute("size", size);
//計算分頁總數
int page;
//如果分頁總數除以顯示條數不等於0
if(size/pageSize!=0) {
//就向上取整分頁的總頁數+1
page=(int)Math.ceil(size/pageSize)+1;
}else {
//不等於0就向上取整分頁的總頁數
page=(int) Math.ceil(size/pageSize);
}
//分頁總頁數
request.setAttribute("page", page);
//把當前頁碼存到request域
request.setAttribute("pageNum", pageNum);
//把集合新增到request作用域
request.setAttribute("user", list);
//轉發到index.jsp介面
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
分頁方法和條數總數方法
package com.zhou;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserDao {
//分頁查詢方法
public static List<User> findAll(int i, int j) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//獲得連線
try {
conn = JdbcUtil.getConnection();
String sql = "select * from user limit ?,?";
//預編譯sql語句
ps= conn.prepareStatement(sql);
//為?賦值
//第一個?
ps.setInt(1, i);
//第二個?
ps.setInt(2, j);
//執行sql語句
rs = ps.executeQuery();
//定義集合儲存user物件
ArrayList<User> list = new ArrayList<User>();
//遍歷結果集
while (rs.next()) {
//通過建構函式遍歷結果集
User user = new User(
rs.getInt("id"),
rs.getString("name"),
rs.getString("password")
);
//新增user物件集合
list.add(user);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtil.close(conn, ps,rs);
}
return null;
}
//獲得總條數方法
public static int Selectsize() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//獲得連線
try {
conn = JdbcUtil.getConnection();
String sql = "select count(*) from user ";
//預編譯sql語句
ps= conn.prepareStatement(sql);
//執行sql語句
rs = ps.executeQuery();
int i=0;
//遍歷結果集
while (rs.next()) {
i=rs.getInt(1);
}
return i;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtil.close(conn, ps,rs);
}
return 0;
}
}
User類
package com.zhou;
public class User {
private Integer id;
private String name;
private String password;
public User(Integer id, String name, String password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
}
}
執行結果
9、jsp+servlet檔案上傳
9.1、檔案上傳
①引入如下jar包
②表單需要設定enctype="multipart/form-data"
以二進位制方式上傳。
③編寫處理上傳檔案的servlet和jsp頁面
jsp介面
<%@ page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"?/"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
package com.zhou;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/fileUpload")
public class FileUpload extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決亂碼問題
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//建立檔案上傳儲存的目錄
String path="E:/upload";
File file = new File(path);
//判斷檔案是否存在不存在就建立
if (!file.exists() ) {
//建立目錄
file.createNewFile();
}
try{
//使用Apache檔案上傳元件處理檔案上傳步驟:
//1、建立一個DiskFileItemFactory工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、建立一個檔案上傳解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//解決上傳檔名的中文亂碼
upload.setHeaderEncoding("UTF-8");
//3、判斷提交上來的資料是否是上傳表單的資料
if(!ServletFileUpload.isMultipartContent(request)){
//按照傳統方式獲取資料
return;
}
//4、使用ServletFileUpload解析器解析上傳資料,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list){
//如果fileitem中封裝的是普通輸入項的資料
if(item.isFormField()){
String name = item.getFieldName();
//解決input輸入的資料中文亂碼問題
String value = item.getString("UTF-8");
//value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
}else{
//如果fileitem中封裝的是上傳檔案
//得到上傳的檔名稱,
String filename = item.getName();
System.out.println(filename);
if(filename==null || filename.trim().equals("")){
continue;
}
//不同的瀏覽器提交的檔名是不一樣的,有些瀏覽器提交上來的檔名是帶有路徑的,而有些只是單純的檔名
//處理獲取到的上傳檔案的檔名的路徑部分,只保留檔名部分
filename = filename.substring(filename.lastIndexOf("\\")+1);
//獲取item中的上傳檔案的輸入流
InputStream in = item.getInputStream();
//建立一個檔案輸出流
FileOutputStream out = new FileOutputStream(path + "\\" + filename);
//建立一個緩衝區
byte buffer[] = new byte[1024];
//判斷輸入流中的資料是否已經讀完的標識
int len = 0;
//迴圈將輸入流讀入到緩衝區當中,(len=in.read(buffer))>0就表示in裡面還有資料
while((len=in.read(buffer))>0){
//使用FileOutputStream輸出流將緩衝區的資料寫入到指定的目錄(savePath + "\\" + filename)當中
out.write(buffer, 0, len);
}
//關閉輸入流
in.close();
//關閉輸出流
out.close();
//刪除處理檔案上傳時生成的臨時檔案
item.delete();
response.getWriter().print("<script>alert('檔案上傳成功!!!')</script>");
}
}
}catch (Exception e) {
response.getWriter().print("<script>alert('檔案上傳失敗!!!')</script>");
e.printStackTrace();
}
}
}
執行結果
相關文章
- Java Servlet和JSP教程(6)(轉)JavaServletJS
- Java Servlet和JSP教程(7)(轉)JavaServletJS
- Java Servlet和JSP教程(8)(轉)JavaServletJS
- Java Servlet和JSP教程(9)(轉)JavaServletJS
- Java Servlet和JSP教程(10)(轉)JavaServletJS
- Java Servlet和JSP教程(11)(轉)JavaServletJS
- Java Servlet和JSP教程(12)(轉)JavaServletJS
- Java Servlet和JSP教程(13)(轉)JavaServletJS
- Java Servlet和JSP教程(1)(轉)JavaServletJS
- Java Servlet和JSP教程(2)(轉)JavaServletJS
- Java Servlet和JSP教程(3)(轉)JavaServletJS
- Java Servlet和JSP教程(4)(轉)JavaServletJS
- Java Servlet和JSP教程(5)(轉)JavaServletJS
- Servlet與JSP進階五:瀏覽器CookieServletJS瀏覽器Cookie
- 深入理解和改進JSP/Servlet會話管理機制JSServlet會話
- Day91.Servlet基本內容① -Servlet、jsp和表示式ServletJS
- jsp servlet javabeanJSServletJavaBean
- JSP與ServletJSServlet
- Jsp和Servlet有什麼區別?JSServlet
- maven中新增Servlet和jsp依賴MavenServletJS
- Java之JSP和Servlet基礎知識。JavaJSServlet
- tomact和javaee、jsp、servlet對應的版本MacJavaJSServlet
- 深入剖析JSP和Servlet對中文的處理JSServlet
- Arthas 進階教程
- Vim進階教程
- jsp+servlet 練習JSServlet
- EJB/JSP/Servlet Sequence GeneratorJSServlet
- 請教一下JSP+SERVLET+EJB結構的進階教材,多謝前人栽樹了JSServlet
- Servlet.service() for Servlet jsp threw exception javax.servlet.ServletException:File "/pageFooServletJSExceptionJava
- Tomcat下JSP、Servlet和JavaBean環境的配置TomcatJSServletJavaBean
- Servlet和JSP規範及版本對應關係ServletJS
- jsp隱式物件-Servlet物件JS物件Servlet
- JSP/Servlet基礎語法JSServlet
- 求助servlet&jsp問題ServletJS
- Python Django進階教程(一)(高階檢視和URL配置)PythonDjango
- Jsp+JavaBean循序漸進教程(六)JSJavaBean
- 6 年前,只會 JSP 和 Servlet 就可以找到工作JSServlet
- 資料恢復基礎和進階教程(二)資料恢復