QL腳本:
CREATE TABLE `t_userinfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(32) DEFAULT '',
`password` varchar(32) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`question` varchar(255) DEFAULT NULL,
`result` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
Java代碼:
package com.demo.dao;
import com.demo.model.UserInfo;
public interface UserInfoDao {
/**
* 保存用戶信息
* @param userinfo
* @return
*/
public boolean saveUserInfo(UserInfo userinfo);
public UserInfo queryUserInfo(String account);
public boolean updateUserInfo(UserInfo userInfo);
}
package com.demo.dao;
import com.demo.model.UserInfo;
import com.demo.tools.JDBConnection;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserInfoDaoImp implements UserInfoDao{
private JDBConnection connection=null;
@Override
public boolean saveUserInfo(UserInfo userinfo) {
connection=new JDBConnection();
boolean flag=false;
StringBuilder sql=new StringBuilder();
sql.append("insert into t_userinfo (account,password,email,question,result) values(?,?,?,?,?)");
String[] pam={userinfo.getAccount(),userinfo.getPassword(),userinfo.getEmail(),userinfo.getQuestion(),userinfo.getResult()};
if (connection.updateData(sql.toString(),pam)) {
flag=true;
}
return flag;
}
@Override
public UserInfo queryUserInfo(String account) {
UserInfo userinfo=null;
connection=new JDBConnection();
try {
String sql="select * from t_userinfo where account=?";
String[] pam={account};
ResultSet rs=connection.queryByPsStatement(sql,pam);
while (rs.next()) {
userinfo=new UserInfo();
userinfo.setId(rs.getInt(1));
userinfo.setAccount(rs.getString(2));
userinfo.setPassword(rs.getString(3));
userinfo.setEmail(rs.getString(4));
userinfo.setQuestion(rs.getString(5));
userinfo.setResult(rs.getString(6));
}
}
catch (SQLException ex) {
return null;
}
finally {
connection.closeAll();
}
return userinfo;
}
@Override
public boolean updateUserInfo(UserInfo userInfo) {
connection=new JDBConnection();
boolean flag=false;
StringBuilder sql=new StringBuilder();
sql.append("update into t_userinfo set password=? where id=?");
String[] pam={userInfo.getPassword(),String.valueOf(userInfo.getId())};
if (connection.updateData(sql.toString(),pam)) {
flag=true;
}
return flag;
}
}
package com.demo.model;
public class UserInfo {
private Integer id=-1;
private String account="";
private String password="";
private String email="";
private String question="";
private String result="";
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id=id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account=account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password=password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email=email;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question=question;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result=result;
}
}
package com.demo.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class PictureCheckCode extends HttpServlet {
private Font mFont=new Font("黑體", Font.BOLD, 17);
public PictureCheckCode() {
super();
}
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void init() throws ServletException {
// Put your code here
super.init();
}
Color getRandColor(int fc, int bc) {
Random random=new Random();
if (fc > 255)
fc=255;
if (bc > 255)
bc=255;
int r=fc + random.nextInt(bc - fc);
int g=fc + random.nextInt(bc - fc);
int b=fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "No-cache");
response.setDateHeader("Expires", 0);
// 指定生成的響應是圖片
response.setContentType("image/jpeg");
int width=70;
int height=19;
BufferedImage image=new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
Random random=new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(1, 1, width - 1, height - 1);
g.setColor(new Color(102, 102, 102));
g.drawRect(0, 0, width - 1, height - 1);
g.setFont(mFont);
g.setColor(getRandColor(160, 200));
// 畫隨機的線條
for (int i=0; i < 155; i++) {
int x=random.nextInt(width - 1);
int y=random.nextInt(height - 1);
int x1=random.nextInt(6) + 1;
int y1=random.nextInt(12) + 1;
g.drawLine(x, y, x + x1, y + y1);
}
String sRand="";
// 輸出隨機的驗證文字
for (int i=0; i < 4; i++) {
int itmp=random.nextInt(26) + 65;
char ctmp=(char) itmp;
sRand +=String.valueOf(ctmp);
g.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
g.drawString(String.valueOf(ctmp), 15 * i + 10, 16);
}
// 將生成的驗證碼保存到Session中
HttpSession session=request.getSession(true);
session.setAttribute("rand", sRand);
g.dispose();
ImageIO.write(image, "JPEG", response.getOutputStream());
}
}
package com.demo.servlet;
import com.demo.dao.UserInfoDao;
import com.demo.dao.UserInfoDaoImp;
import com.demo.model.UserInfo;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;
public class UserInfoServlet extends HttpServlet {
private int method;
private UserInfo userInfo=null;
private UserInfoDao userInfoDaoImp=null;
private HttpSession session=null;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
method=Integer.parseInt(request.getParameter("method"));
if (method==1) {
this.checkAccount(request, response);
}
if (method==2) {
this.register(request, response);
}
if (method==3) {
this.findPS1(request, response);
}
if (method==4) {
this.findPS2(request, response);
}
}
private void sendEmail(String content) {
try {
String from="sk666888@sohu.com";
String to="wgh717@sohu.com";
String subject="找回密碼";
String messageText=content;
String password="111111";
String mailserver="smtp.qq.com";
Properties prop=new Properties();
// 設置郵件服務器主機名
prop.put("mail.smtp.host", mailserver);
// 發送服務器需要身份驗證
prop.put("mail.smtp.auth", "true");
MailSSLSocketFactory sf=new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
Session sess=Session.getInstance(prop);
sess.setDebug(true);
MimeMessage message=new MimeMessage(sess);
// 給消息對象設置收件人、發件人、主題、發信時間
InternetAddress mail_from=new InternetAddress(from);
message.setFrom(mail_from);
InternetAddress mail_to=new InternetAddress(to);
message.setRecipient(Message.RecipientType.TO, mail_to);
message.setSubject(subject);
message.setSentDate(new Date());
// 新建一個MimeMultipart對象來存放多個BodyPart對象
Multipart mul=new MimeMultipart();
// 新建一個存放信件內容的BodyPart對象
BodyPart mdp=new MimeBodyPart();
mdp.setContent(messageText, "text/html;charset=gb2312");
// 將含有信件內容的BodyPart加入到MimeMulitipart對象中
mul.addBodyPart(mdp);
// 把mul作為消息對象的內容
message.setContent(mul);
message.saveChanges();
Transport transport=sess.getTransport("smtp");
// 以smtp方式登陸郵箱,第1個參數是發送郵件用的郵件服務器SMTP地址,第2個參數為用戶名,第3個參數為密碼
transport.connect(mailserver, from, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch (Exception e) {
System.out.println("發送郵件產生的錯誤:" + e.getMessage());
}
}
private void findPS2(HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException,
ServletException, IOException {
userInfoDaoImp=new UserInfoDaoImp();
String account=new String(request.getParameter("account").getBytes(
"ISO8859_1"), "UTF-8");
UserInfo userInfo=userInfoDaoImp.queryUserInfo(account);
String result=new String(request.getParameter("result").getBytes(
"ISO8859_1"), "UTF-8");
if (result.equals(userInfo.getResult())) {
String password="111";
String enPasswor=com.demo.tools.Encrypt.encodeMD5(password);
userInfo.setPassword(enPasswor);
userInfoDaoImp.updateUserInfo(userInfo);
String content="您的密碼是:" + password + ",請您牢記!";
sendEmail(content);
request.setAttribute("information", "已經將您的密碼發送到郵箱!");
}
else {
request.setAttribute("information", "您輸入的密碼答案不正確!");
}
request.getRequestDispatcher("findPS2.jsp").forward(request, response);
}
private void findPS1(HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException,
ServletException, IOException {
userInfoDaoImp=new UserInfoDaoImp();
String account=new String(request.getParameter("account").getBytes(
"ISO8859_1"), "gb2312");
UserInfo userInfo=userInfoDaoImp.queryUserInfo(account);
if (null !=userInfo) {
request.setAttribute("userInfo", userInfo);
request.getRequestDispatcher("findPS2.jsp").forward(request, response);
} else {
request.setAttribute("information", "您輸入用戶并不存在!");
request.getRequestDispatcher("findPS1.jsp").forward(request, response);
}
}
private void checkAccount(HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException,
ServletException, IOException {
String information="";
userInfoDaoImp=new UserInfoDaoImp();
session=request.getSession();
String rand=(String) session.getAttribute("rand");
String code=(String) request.getParameter("code");
String account=request.getParameter("account");
String password=request.getParameter("password");
if (com.demo.tools.Encrypt.isValidInput(account)
&& com.demo.tools.Encrypt.isValidInput(password)) {
account=new String(account.getBytes("ISO8859_1"), "gb2312");
password=com.demo.tools.Encrypt.encodeMD5(password);
}
else {
information="您輸入的用戶或密碼存在非法字符串";
}
if (information.equals("")) {
if (rand.equals(code)) {
userInfo=userInfoDaoImp.queryUserInfo(account);
if (null !=userInfo) {
if (userInfo.getPassword().equals(password)) {
session.setAttribute("userInfo", userInfo);
}
else {
information="您輸入的密碼不正確";
}
}
else {
information="您輸入的用戶名不存在!";
}
}
else {
information="您輸入的驗證碼不正確!";
}
}
System.out.println(information);
request.setAttribute("information", information);
request.getRequestDispatcher("index.jsp").forward(request, response);
}
private void register(HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException,
ServletException, IOException {
String information="";
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
userInfo=new UserInfo();
userInfoDaoImp=new UserInfoDaoImp();
session=request.getSession();
String rand=(String) session.getAttribute("rand");
String code=(String) request.getParameter("code");
String account=request.getParameter("account");
String password=request.getParameter("password");
if (com.demo.tools.Encrypt.isValidInput(account)
&& com.demo.tools.Encrypt.isValidInput(password)) {
account=new String(account.getBytes("ISO8859_1"), "UTF-8");
password=com.demo.tools.Encrypt.encodeMD5(password);
}
else {
information="您輸入的用戶或密碼存在非法字符串";
}
if (information.equals("")) {
if (rand.equals(code)) {
userInfo.setAccount(account);
userInfo.setPassword(password);
userInfo.setEmail(request.getParameter("email"));
userInfo.setQuestion(new String(request
.getParameter("question").getBytes("ISO8859_1"),
"UTF-8"));
userInfo.setResult(new String(request.getParameter("result")
.getBytes("ISO8859_1"), "UTF-8"));
System.out.println(userInfo);
if (!userInfoDaoImp.saveUserInfo(userInfo)) {
information="您輸入的用戶名已經存在!";
}
}
else {
information="您輸入的校驗碼不正確!";
}
if (information.equals("")) {
information="您注冊成功!";
request.setAttribute("information", information);
request.getRequestDispatcher("register.jsp").forward(request, response);
}
else {
out.print("<script language=javascript>alert('" + information
+ "');window.location.href='register.jsp';</script>");
}
}
else {
out.print("<script language=javascript>alert('" + information
+ "');window.location.href='register.jsp';</script>");
}
}
}
package com.demo.tools;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Encrypt {
public static String encodeMD5(String str) {
if (null==str) {
return null;
}
StringBuilder sb=new StringBuilder();
try {
MessageDigest code=MessageDigest.getInstance("MD5");
code.update(str.getBytes());
byte[] bs=code.digest();
for (int i=0; i < bs.length; i++) {
int v=bs[i] & 0xFF;
if (v < 16) {
sb.append(0);
}
sb.append(Integer.toHexString(v));
}
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return sb.toString().toUpperCase();
}
public static boolean isValidInput(String str) {
return str.matches("[a-z0-9]+");
}
}
package com.demo.tools;
import java.sql.*;
public class JDBConnection {
private final String dbDriver="com.mysql.jdbc.Driver";
private final String url="jdbc:mysql://localhost:3306/testdb?useUnicode&characterEncodiing=utf-8&useSSL=true&rewriteBatchedStatements=true";
private final String userName="root";
private final String password="root";
private ResultSet rs=null;
private Statement stmt=null;
private Connection con=null;
private PreparedStatement preparedStatement=null;
public JDBConnection() {
try {
Class.forName(dbDriver).newInstance();
}
catch (Exception ex) {
System.out.println("數據庫加載失敗");
}
}
private boolean creatConnection() {
try {
con=DriverManager.getConnection(url, userName, password);
con.setAutoCommit(true);
return true;
}
catch (SQLException e) {
System.out.println(e.getMessage());
return false;
}
}
private void createPsStatement(String sql) {
creatConnection();
try {
System.out.println("創建PrepareStatement通道對象。。。");
preparedStatement=con.prepareStatement(sql);
}
catch (SQLException e) {
System.out.println("創建PrepareStatement通道對象失敗。。。");
e.printStackTrace();
}
}
private void bundle(String[] parm) {
//判斷數組Parm是否為空
if (parm !=null) {
//通過for循環將參數綁定起來
for (int i=0; i < parm.length; i++) {
try {
System.out.println( "進行參數的綁定。。。");
preparedStatement.setString(i + 1, parm[i]);
}
catch (SQLException e) {
System.out.println("綁定參數失敗。。。");
e.printStackTrace();
}
}
}
}
public ResultSet queryByPsStatement(String sql,String[] pram) {
createPsStatement(sql);
bundle(pram);
try {
System.out.println("采用PrepareStatement方法執行sql查詢語句。。。");
rs=preparedStatement .executeQuery();
}
catch (SQLException e) {
System.out.println("采用PrepareStatement方法執行sql查詢語句失敗");
e.printStackTrace();
}
return rs;
}
public Boolean updateData(String sql,String[] parm) {
//創建通道
createPsStatement(sql);
//綁定參數
bundle(parm);
int row=0;
try {
System.out.println("修改數據中。。。");
row=preparedStatement.executeUpdate();
} catch (SQLException e) {
System.out.println("修改數據失敗。。。");
e.printStackTrace();
}
boolean res=false;
if (row > 0) {
res=true;
}
return res;
}
public void closeAll() {
if (rs !=null) {
try {
System.out.println("關閉resultSet。。。");
rs.close();
} catch (SQLException e) {
System.out.println("關閉resultSet異常。。。");
e.printStackTrace();
}
}
if (stmt !=null) {
try {
System.out.println("關閉statement。。。");
stmt.close();
} catch (SQLException e) {
System.out.println("關閉statement異常。。。");
e.printStackTrace();
}
}
if (preparedStatement !=null) {
try {
System.out.println("關閉preparestatement。。。");
preparedStatement .close();
} catch (SQLException e) {
System.out.println("關閉preparestatement異常。。。");
e.printStackTrace();
}
}
if (con !=null) {
try {
System.out.println("關閉connection。。。");
con.close();
} catch (SQLException e) {
System.out.println("關閉connection異常。。。");
e.printStackTrace();
}
}
}
}
CSS代碼:
td {
font-size: 9pt;
color: #000000;
}
a:hover {
font-size: 9pt;
color: #FF0000;
}
a {
font-size: 9pt;
text-decoration: none;
color: #000000;
}
img{
border:0;
}
.img1{
border:1px;
}
.blue {
font-size: 9pt;
color: #034683;
}
.bgcolor {
font-size: 9pt;
color: #1980DB;
}
.btn_grey {
font-family: "宋體";
font-size: 9pt;
color: #333333;
background-color: #eeeeee;
cursor: hand;
padding:1px;
height:19px;
border-top: 1px solid #FFFFFF;
border-right:1px solid #666666;
border-bottom: 1px solid #666666;
border-left: 1px solid #FFFFFF;
}
input{
font-family: "宋體";
font-size: 9pt;
color: #333333;
border: 1px solid #999999;
}
.word_white{
color:#FFFFFF;
}
.word_deepgrey{
color:#999999;
}
.word_orange{
color:#FF6600;
}
.word_green{
color:#FEECEA;
}
.noborder{
border:none;
}
.word_gray{
color:#dddddd;
}
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}
textarea {
font-family: "宋體";
font-size: 9pt;
color: #333333;
border: 1px solid #999999;
}
hr{
border-style:dashed;
color:#CCCCCC;
}
Javascript代碼:
function validteCode()
{
//用于存儲隨機驗證碼
let codes=new Array(4);
let colors=new Array("Red","Green","Gray","Blue","Maroon","Aqua","Fuchsia","Lime","Olive","Silver");
for(let i=0;i < codes.length;i++)
{
//獲取隨機驗證碼
codes[i]=Math.floor(Math.random()*10);
}
let spans=document.getElementById("divCode").all;
for(let i=0;i<spans.length;i++)
{
spans[i].innerHTML=codes[i];
//隨機設置驗證碼顏色
spans[i].style.color=colors[Math.floor(Math.random()*10)];
}
}
document.onload=validteCode();
JSP頁面代碼:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>用戶登錄</title>
<link href="css/style.css" type="text/css" rel="stylesheet">
<script language="javascript">
function reload(){
//document.checkCode.src="PictureCheckCode";
document.getElementById("checkCode").src=document.getElementById("checkCode").src+"?nocache="+new Date().getTime();
}
function checkEmpty(form){
for(let i=0;i<form.length;i++){
if(form.elements[i].value==""){
alert(form.elements[i].title);
return false;
}
}
}
</script>
</head>
<body>
<br>
<table width="766" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="496" valign="top">
<table width="496" height="205" border="0" cellpadding="0"
cellspacing="0" background="images/banne.jpg">
<tr>
<td width="204">
</td>
<td width="278" class="line">
<b>關于工作室</b>
<br>
<br>
工作室是由幾個志同道合的朋友一起創辦的集博客、論壇、空間、新聞等8大功能于一身的門戶網站機構、先已擁有800萬固定網友......
<br>
<br>
<a href="register.jsp" class="a3">現在注冊 >></a>
</td>
<td width="14">
</td>
</tr>
</table>
<table width="496" border="0" cellpadding="0" cellspacing="0"
background="images/char.jpg">
<tr>
<td height="31" class="word">
</td>
</tr>
</table>
<table width="496" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="55" height="233">
<img src="images/left.jpg" width="55" height="233">
</td>
<td width="10">
</td>
<td width="212" valign="top">
<table width="205" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="45" valign="bottom" class="word">
<span class="lineline"><strong>空間</strong>
<br> 提供50MB免費空間,支持MySQL數據庫</span>
</td>
</tr>
</table>
<table width="205" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="54" valign="bottom" class="word">
<span class="lineline"><strong>博客</strong>
<br> 新近研發博客搬家工具,方便之門</span>
</td>
</tr>
</table>
<table width="205" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="58" valign="bottom" class="word">
<span class="lineline"><strong>新聞</strong>
<br> 最新最全的國內外大事全記錄</span>
</td>
</tr>
</table>
<table width="205" border="0" cellpadding="0" cellspacing="0">
<tr>
<td height="56" valign="bottom" class="word">
<span class="lineline"><strong>文檔</strong>
<br> 還在費力的到處查找文檔嗎,快請進</span>
</td>
</tr>
</table>
</td>
<td width="34">
<img src="images/right.jpg" width="34" height="233">
</td>
<td width="10">
</td>
<td width="175" valign="top">
<table width="168" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="168" height="45" valign="bottom" class="word">
<span class="lineline"><strong>空間</strong>
<br> 30位斑竹熱聘中....</span>
</td>
</tr>
</table>
<table width="163" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="163" height="54" valign="bottom" class="word">
<span class="lineline"><strong>下載</strong>
<br> 500萬資源供您下載</span>
</td>
</tr>
</table>
<table width="167" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="167" height="58" valign="bottom" class="word">
<span class="lineline"><strong>網摘</strong>
<br> 就像天空的浮云一樣</span>
</td>
</tr>
</table>
<table width="166" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="166" height="56" valign="bottom" class="word">
<span class="lineline"><strong>讀書</strong>
<br> 讀書“武裝”自己
</span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td width="270" valign="top">
<table width="237" border="0" align="center" cellpadding="0"
cellspacing="0">
<tr>
<td height="18" align="center">
<a href="#" class="a4">設為首頁</a> /
<a href="#" class="a4">加入收藏</a> /
<a href="#" class="a4">聯系我們</a>
</td>
</tr>
</table>
<table width="128" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<img src="images/land.jpg" width="270" height="56">
</td>
</tr>
</table>
<table width="270" height="304" border="0" cellpadding="0"
cellspacing="0">
<tr>
<td background="images/land1.jpg" valign="top">
<%
if (null==session.getAttribute("userInfo")) {
%>
<form name="form" method="post" action="userInfo?method=1"
onSubmit="return checkEmpty(form)">
<table width="231" border="0" align="center">
<tr>
<td width="53" height="25">
登錄名:
</td>
<td width="168" height="25">
<input type="text" name="account" title="請輸入登錄用戶名">
</td>
</tr>
<tr>
<td height="25">
密 碼:
</td>
<td height="25">
<input type="password" name="password" title="請輸入登錄密碼">
</td>
</tr>
<tr>
<td height="25">
校驗碼:
</td>
<td height="25">
<input type="text" name="code" title="請輸入驗證碼">
</td>
</tr>
<tr>
<td height="25" colspan="2" align="center" valign="middle">
<table width="185" border="0" cellpadding="0"
cellspacing="0">
<tr>
<td width="69">
<img border=0 src="PictureCheckCode" id="checkCode">
</td>
<td width="116">
<a href="#" onClick="reload();" class="a2">重新獲得驗證碼</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td height="25" colspan="2" align="center">
<input name="Submit" type="image" class="noborder" src="images/land.png">
</td>
</tr>
<tr>
<td height="15" colspan="2" align="center">
<a href="register.jsp" class="a2">沒有注冊?點此處注冊</a>
<br>
<br>
<a href="findPS1.jsp" class="a2">如果密碼丟失?請找回密碼</a>
</td>
</tr>
</table>
</form>
<div align="center">
${requestScope.information}
<%
}
else {
%>
<br>
<br>
</div>
<table width="230" border="0" align="center">
<tr>
<td height="20">用 戶 名:</td>
<td>
${sessionScope.userInfo.account}
</td>
</tr>
<tr>
<td height="20">聯系郵箱:</td>
<td>
${sessionScope.userInfo.email}
</td>
</tr>
<tr>
<td height="20">
</td>
<td>
<a href="loginOut.jsp" class="a2">重新登錄</a>
</td>
</tr>
</table>
<%
}
%>
</td>
</tr>
</table>
<table width="270" height="69" border="0" cellpadding="0"
cellspacing="0" background="images/cidian.jpg">
<tr>
<td width="87">
</td>
<td width="183" class="lineline">
<strong><a href="#" class="a5">編程詞典</a>(程序學習工具)</strong>
<br>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="766" height="80" border="0" align="center"
cellpadding="0" cellspacing="0" background="images/downLine.jpg">
<tr>
<td align="center">
<font color="#666666">
<br> Copyright? 2008
</font>
</td>
</tr>
</table>
</body>
</html>
register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="css/style.css" type="text/css" rel="stylesheet">
<title>用戶注冊</title>
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<meta HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<meta HTTP-EQUIV="Expires" CONTENT="0">
<script language="javascript">
function checkemail(email){
var str=email;
//在JavaScript中,正則表達式只能使用"/"開頭和結束,不能使用雙引號
var Expression=/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
var objExp=new RegExp(Expression);
if(objExp.test(str)==true){
return true;
}else{
return false;
}
}
function checkForm(form){
if(form.account.value==""){
window.alert("請輸入用戶登錄昵稱!");
return false;
}
if(form.account.value.length < 5 ||form.account.value.length > 20){
window.alert("用戶登錄昵稱必須在5-20之間!");
return false;
}
if(form.password.value==""){
window.alert("請輸入用戶登錄密碼!");
return false;
}
if(form.password.value.length < 8){
window.alert("用戶登錄密碼必須在8位以上");
return false;
}
if(form.repassword.value==""){
window.alert("請輸入用戶登錄重復密碼!");
return false;
}
if(form.repassword.value!=form.password.value){
window.alert("您輸入的兩次密碼都不正確!");
return false;
}
if(form.email.value==""){
window.alert("請輸入email地址");
return false;
}
if(!checkemail(form.email.value)){
window.alert("您輸入的email地址格式不正確");
return false;
}
if(form.code.value==""){
window.alert("請輸入校驗碼");
return false;
}
}
function reload(){
document.getElementById("checkCode").src=document.getElementById("checkCode").src+"?nocache="+new Date().getTime();
}
</script>
</head>
<body>
<table width="765" height="120" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_top.jpg">
<tr>
<td width="520"> </td>
<td width="245" valign="top">
<table width="214" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="252" height="43" valign="bottom">
<a href="#" class="a2">設為首頁</a> /
<a href="#" class="a2">加入收藏</a> /
<a href="#" class="a2">聯系我們</a>
</td>
</tr>
</table></td>
</tr>
</table>
<table width="765" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_center.jpg">
<tr>
<td width="538" height="93" align="center">
<form name="form" method="post" action="userInfo?method=2" onSubmit="return checkForm(form)">
<table width="509" height="290" border="0" align="center">
<tr>
<td width="150" height="30" align="right">用戶登錄昵稱:</td>
<td colspan="2">
<input name="account" type="text"> *
</td>
</tr>
<tr>
<td width="150" height="30" align="right"> </td>
<td colspan="2">5-20位字母、數字或字符組合,首字母必須為字母。</td>
</tr>
<tr>
<td height="30" align="right"> </td>
<td colspan="2">為了您的帳戶安全,強烈建議你的密碼使用字符+數字+特殊字符方式,并且密碼的長度大于8位。</td>
</tr>
<tr>
<td height="30" align="right">密碼:</td>
<td colspan="2">
<input name="password" type="password"> *
</td>
</tr>
<tr>
<td height="30" align="right">重復輸入密碼:</td>
<td colspan="2">
<input name="repassword" type="password"> *
</td>
</tr>
<tr>
<td height="30" align="right"> </td>
<td colspan="2">
注意:郵箱必須可以收到狼族工作室激活碼的。<br>
用戶注冊后,需要激活,才可以使用!激活碼只會發到你注冊郵箱中。
</td>
</tr>
<tr>
<td height="30" align="right">Email地址:</td>
<td colspan="2">
<input name="email" type="text" size="40"> *
</td>
</tr>
<tr>
<td height="30" colspan="3" align="center">
以下兩個選項,只要有任何一個沒有輸入,你將不可能使用通過答案問題新設置密碼的功能。
</td>
</tr>
<tr>
<td height="30" align="right"> </td>
<td colspan="2" valign="bottom">用戶幫您找回忘記的密碼!</td>
</tr>
<tr>
<td height="30" align="right">密碼提示問題:</td>
<td colspan="2">
<input name="question" type="text" id="question" size="50">
</td>
</tr>
<tr>
<td height="30" align="right"> </td>
<td colspan="2" valign="bottom">用戶幫您找回忘記的密碼!</td>
</tr>
<tr>
<td height="30" align="right">提示問題答案:</td>
<td colspan="2">
<input name="result" type="text" id="result" size="50">
</td>
</tr>
<tr>
<td height="30" align="right">校驗碼:</td>
<td colspan="2">
<img border=0 src="PictureCheckCode" id="checkCode">
</td>
</tr>
<tr>
<td height="30" align="right"> </td>
<td colspan="2">
<a href="#" onClick="reload()">重新獲得驗證碼</a>
</td>
</tr>
<tr>
<td height="30" align="right">輸入校驗碼:</td>
<td colspan="2">
<input name="code" type="text"> *</td>
</tr>
<tr>
<td height="30"> </td>
<td width="307">
<input type="submit" name="Submit" value=" 注 冊 用 戶 ">
</td>
<td width="83">
<a href="index.jsp" class="a2">返回登錄</a>
</td>
</tr>
<tr>
<td height="30"> </td>
<td colspan="2">${requestScope.information}</td>
</tr>
</table>
</form>
</td>
<td width="227">
<table width="174" height="546" border="0" align="center">
<tr>
<td width="164" height="35">會員幫助</td>
</tr>
<tr>
<td><p>A:已注冊但未激活的用戶</p>
<p><a href="#" class="a6">馬上激活我的帳戶</a></p></td>
</tr>
<tr>
<td height="68">如果的激活碼丟失,你可以:
<a href="#" class="a6">重新通過郵箱獲取激活碼</a>(發送到你的注冊郵箱)
</td>
</tr>
<tr>
<td height="55">如果你的注冊郵箱沒有接收到激活碼,你可以:
<a href="#" class="a6">修改你的注冊郵箱</a>(必須知道帳戶密碼)
</td>
</tr>
<tr>
<td height="30">B:已激活卻忘記了密碼的用戶</td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">通過回答問題新設密碼</a></td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">把新設密碼的連接發到注冊Email</a></td>
</tr>
<tr>
<td height="30">C:已登錄用戶</td>
</tr>
<tr>
<td height="48">
<a href="#" class="a2">注銷登錄</a>
<a href="#" class="a2">修改提示問題與答案</a><br> <br>
<a href="#" class="a2">修改注冊郵箱</a>
<a href="#" class="a2">新設密碼</a>
</td>
</tr>
<tr>
<td height="30">D:注冊條款</td>
</tr>
<tr>
<td height="133">
建議意見以及錯誤反饋請發送郵件到以下郵箱:
<a href="#" class="a2">XXX@163.com</a><br>
需要咨詢時候,請務必把你的注冊用戶名、注冊Email、以及其他證明這個賬號屬于你的信息一起發過來。<br>
有bug反饋的時候,請務必把出現的bug的操作過程,必要的截圖一起發過來。
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="765" height="90" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_down.jpg">
<tr>
<td align="center">
<font color="#666666">Copyright? 2008 </font>
</td>
</tr>
</table>
</body>
</html>
findPS1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>工作室-找回密碼第一步</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
<link href="css/style.css" type="text/css" rel="stylesheet">
<script language="javascript">
function checkForm(form){
if(form.account.value==""){
window.alert("請輸入用戶登錄昵稱!");
return false;
}
}
</script>
</head>
<body>
<table width="765" height="120" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_top.jpg">
<tr>
<td width="520"> </td>
<td width="245" valign="top"><table width="214" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="252" height="43" valign="bottom">
<a href="#" class="a2">設為首頁</a> /
<a href="#" class="a2">加入收藏</a> /
<a href="#" class="a2">聯系我們</a>
</td>
</tr>
</table></td>
</tr>
</table>
<table width="765" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_center.jpg">
<tr>
<td width="538" height="93" align="center" valign="top">
請輸入用戶昵稱<br>
<br>
<form name="form" method="post" action="userInfo?method=3" onSubmit="return checkForm(form)">
<table width="367" border="0">
<tr>
<td width="99" height="25">用戶登錄昵稱:</td>
<td width="163" colspan="2"><input name="account" type="text"></td>
</tr>
<tr>
<td height="25"> </td>
<td><input type="submit" name="Submit" value=" 提 交 用 戶 "></td>
<td><a href="index.jsp" class="a2">返回登錄</a></td>
</tr>
<tr>
<td height="30"> </td>
<td colspan="3">${requestScope.information}</td>
</tr>
</table>
</form>
</td>
<td width="227">
<table width="174" height="546" border="0" align="center">
<tr>
<td width="164" height="35">會員幫助</td>
</tr>
<tr>
<td><p>A:已注冊但未激活的用戶</p>
<p><a href="#" class="a6">馬上激活我的帳戶</a></p></td>
</tr>
<tr>
<td height="68">如果的激活碼丟失,你可以:
<a href="#" class="a6">重新通過郵箱獲取激活碼</a>(發送到你的注冊郵箱)
</td>
</tr>
<tr>
<td height="55">如果你的注冊郵箱沒有接收到激活碼,你可以:
<a href="#" class="a6">修改你的注冊郵箱</a>(必須知道帳戶密碼)
</td>
</tr>
<tr>
<td height="30">B:已激活卻忘記了密碼的用戶</td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">通過回答問題新設密碼</a></td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">把新設密碼的連接發到注冊Email</a></td>
</tr>
<tr>
<td height="30">C:已登錄用戶</td>
</tr>
<tr>
<td height="48">
<a href="#" class="a2">注銷登錄</a>
<a href="#" class="a2">修改提示問題與答案</a><br> <br>
<a href="#" class="a2">修改注冊郵箱</a>
<a href="#" class="a2">新設密碼</a>
</td>
</tr>
<tr>
<td height="30">D:注冊條款</td>
</tr>
<tr>
<td height="133">
建議意見以及錯誤反饋請發送郵件到以下郵箱:<a href="#" class="a2">XXX@163.com</a><br>
需要咨詢時候,請務必把你的注冊用戶名、注冊Email、以及其他證明這個賬號屬于你的信息一起發過來。<br>
有bug反饋的時候,請務必把出現的bug的操作過程,必要的截圖一起發過來。
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="765" height="90" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_down.jpg">
<tr>
<td align="center">
<font color="#666666">
Copyright? 2008 All Right Reserved!
</font>
</td>
</tr>
</table>
</body>
</html>
findPS2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>工作室-找回密碼第二步</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="css/style.css" type="text/css" rel="stylesheet">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
<script language="javascript">
function checkForm(form){
if(form.result.value==""){
window.alert("請輸入問題答案!");
return false;
}
}
</script>
</head>
<body>
<table width="765" height="120" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_top.jpg">
<tr>
<td width="520"> </td>
<td width="245" valign="top">
<table width="214" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="252" height="43" valign="bottom">
<a href="#" class="a2">設為首頁</a> /
<a href="#" class="a2">加入收藏</a> /
<a href="#" class="a2">聯系我們</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="765" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_center.jpg">
<tr>
<td width="538" height="93" align="center" valign="top">
請輸入問題答案<br>
<br>
<form name="form" method="post" action="userInfo?method=4" onSubmit="return checkForm(form)">
<table width="367" border="0">
<tr>
<td width="99" height="25">問題:</td>
<td width="163" colspan="2">${requestScope.userInfo.question}</td>
</tr>
<tr>
<td width="99" height="25">答案:</td>
<td width="163" colspan="2"><input name="result" type="text">
<input name="account" type="hidden" value="${requestScope.userInfo.account}">
</td>
</tr>
<tr>
<td height="25"> </td>
<td><input type="submit" name="Submit" value=" 提 交 答 案 "></td>
<td><a href="index.jsp" class="a2">返回登錄</a></td>
</tr>
<tr>
<td height="30"> </td>
<td colspan="3">${requestScope.information}</td>
</tr>
</table>
</form> </td>
<td width="227">
<table width="174" height="546" border="0" align="center">
<tr>
<td width="164" height="35">會員幫助</td>
</tr>
<tr>
<td><p>A:已注冊但未激活的用戶</p>
<p><a href="#" class="a6">馬上激活我的帳戶</a></p></td>
</tr>
<tr>
<td height="68">如果的激活碼丟失,你可以:
<a href="#" class="a6">重新通過郵箱獲取激活碼</a>(發送到你的注冊郵箱)
</td>
</tr>
<tr>
<td height="55">如果你的注冊郵箱沒有接收到激活碼,你可以:
<a href="#" class="a6">修改你的注冊郵箱</a>(必須知道帳戶密碼)
</td>
</tr>
<tr>
<td height="30">B:已激活卻忘記了密碼的用戶</td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">通過回答問題新設密碼</a></td>
</tr>
<tr>
<td height="20"><a href="#" class="a2">把新設密碼的連接發到注冊Email</a></td>
</tr>
<tr>
<td height="30">C:已登錄用戶</td>
</tr>
<tr>
<td height="48">
<a href="#" class="a2">注銷登錄</a>
<a href="#" class="a2">修改提示問題與答案</a><br> <br>
<a href="#" class="a2">修改注冊郵箱</a>
<a href="#" class="a2">新設密碼</a>
</td>
</tr>
<tr>
<td height="30">D:注冊條款</td>
</tr>
<tr>
<td height="133">
建議意見以及錯誤反饋請發送郵件到以下郵箱:<a href="#" class="a2">XXX@163.com</a><br>
需要咨詢時候,請務必把你的注冊用戶名、注冊Email、以及其他證明這個賬號屬于你的信息一起發過來。<br>
有bug反饋的時候,請務必把出現的bug的操作過程,必要的截圖一起發過來。
</td>
</tr>
</table>
</td>
</tr>
</table>
<table width="765" height="90" border="0" align="center" cellpadding="0" cellspacing="0" background="images/re_down.jpg">
<tr>
<td align="center">
<font color="#666666">
Copyright? 2008 All Right Reserved!
</font>
</td>
</tr>
</table>
</body>
</html>
loginOut.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>退出登錄</title>
</head>
<body>
<%
session.invalidate();
response.sendRedirect("index.jsp");
%>
</body>
</html>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>registerDemo</display-name>
<servlet>
<servlet-name>UserInfoServlet</servlet-name>
<servlet-class>com.demo.servlet.UserInfoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>PictureCheckCode</servlet-name>
<servlet-class>com.demo.servlet.PictureCheckCode</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserInfoServlet</servlet-name>
<url-pattern>/userInfo</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PictureCheckCode</servlet-name>
<url-pattern>/PictureCheckCode</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
maven:
avaServer Pages(JSP) 是一種服務器端編程技術,能夠為構建基于 Web 的應用程序創建動態的獨立于平臺的方法。JSP 可以訪問 Java API 的整個家族,包括訪問企業級數據庫的 JDBC API。
本文章幫助初學者們了解 JavaServer Pages(JSP) 的基本功能,從而開發自己的 Web 應用程序。學習后你會發現自己處于一個使用 JSP 專業知識的中等水平,之后你可以達到更高的水平。
搭配視頻觀看效果更佳~~
Jsp入門到精通
https://www.ixigua.com/6772333813507817987
JSP全稱Java Server Pages,是一種動態網頁開發技術。它使用JSP標簽在HTML網頁中插入Java代碼。標簽通常以<%開頭以%>結束。
JSP是一種Java servlet,主要用于實現Java web應用程序的用戶界面部分。網頁開發者們通過結合HTML代碼、XHTML代碼、XML元素以及嵌入JSP操作和命令來編寫JSP。
JSP通過網頁表單獲取用戶輸入數據、訪問數據庫及其他數據源,然后動態地創建網頁。
JSP標簽有多種功能,比如訪問數據庫、記錄用戶選擇信息、訪問JavaBeans組件等,還可以在不同的網頁中傳遞控制信息和共享信息。
● 能以模板化的方式簡單、高效地添加動態網頁內容。
● 可利用JavaBean和標簽庫技術復用常用的功能代碼(設計好的組件容易實現重復利用,減少重復勞動)。標簽庫不僅帶有通用的內置標簽(JSTL),而且支持可擴展功能的自定義標簽。
●有良好的工具支持。
● 繼承了Java語言的相對易用性。
● 繼承了Java的跨平臺優勢,實現“一次編寫,處處運行”。因為支持Java及其相關技術的開發平臺多,網站開發人員可以選擇在最適合自己的系統平臺上進行JSP開發;不同環境下開發的JSP項目,在所有客戶端上都能順利訪問。
● 頁面中的動(控制變動內容的部分)/靜(內容不需變動的部分)區域以分散但又有序的形式組合在一起,能使人更直觀地看出頁面代碼的整體結構,也使得設計頁面效果和程序邏輯這2部分工作容易分離(外觀視圖與邏輯分離)。從而方便分配人員并發揮各自長處,實現高效地分工合作。
● 可與其它企業級Java技術相互配合。JSP可以只專門負責頁面中的數據呈現,實現分層開發。
一、介紹:
1.JSP是sun公司提供一個規范
2.JSP規范用于封裝響應對象簡化將Servlet處理結果寫入到響應體開發難度
二、響應對象使用時問題
1.手動設置響應頭content-type
2.手動索要一個輸出流對象
3.手動將結果寫入到響應體
三、JSP優勢
開發人員你只需考慮哪些內容需要寫入到響應體不需要考慮寫入到響應包中過程
jsp文件"運行時"自動將文件內部所有與Java命令無關()的內容自動寫入到響應體
四、jsp文件中java命令書寫規范
1.執行標簽
1) 格式: :
<%
java命令行;
%>
2) 作用:用于提示JSP文件在運行時不要將執行標簽中Java命令寫入到響應體通知JSP文件在運行時需要將執行標簽中內容執行完畢后再做輸出
3) java命令行:
2.輸出標簽
1) 格式::
<%=變量名%>
<%=運算表達式%>
2) 作用:
在jsp文件運行時,通知JSP將指定變量內容或則表達式結果寫入到響應體
五、jsp文件中內置對象---九
1.ServletContext application
2. HttpSession session
3.HttpServletRequest request
六、Servlet與jsp文件之間關系
1.Servlet: 接收請求并處理請求,但是Servlet不負責將處理結果返回
-----相當于"大廚"
2.JSP:不負責處理請求,負責將Servlet生成的處理結果寫入到響應體
-----相當于"傳菜員"
3.Servlet與jsp之間調用關系
請求轉發
瀏覽器------>Servlet(處理請求)----------->jsp--->處理結果寫入到響應體
4.Servlet與jsp之間如何共享數據借助于request
七、JSP運行原理【面試必考題】
1.JSP文件不是靜態資源文件也不是動態資源文件
2.JSP文件不能被編譯不能被調用執行
3.運行原理:
1)tomcat接收到調用jsp文件(one.jsp)請求時,tomcat將被訪問jsp【編輯】為java文件(one_jsp.java)
2)tomcat調用JVM將java文件【編譯】為class文件(one_jsp.class)
3) 這個class文件是一個Servlet接口實現類
4)tomcat通過反射機制生成這個class文件的實例對象
5)tomcat通過實例對象調用_jspService方法,這個方法在運行時負責通過輸出流將jsp文件內容寫入到響應體
文轉自與博客園一杯涼茶的博客
前面講解了Servlet,了解了Servlet的繼承結構,生命周期等,并且在其中的ServletConfig和ServletContext對象有了一些比較詳細的了解,但是我們會發現在Servlet中編寫一些HTML代碼,是很不方便的一件事情,每次都需要out.println(HTML); 因此就出現了JSP,來解決這樣的問題,JSP中的內容就是html,但是能夠嵌套java語言,現在來詳細了解一下JSP。
1、什么是JSP?
JSP(Java Server Pages):是以Java語言為基礎的動態網頁開發技術,
特點:
Servlet特點:在Java源碼中嵌入html源碼
JSP特點:在html源碼中嵌入java代碼
JSP就是Servlet
1、tomcat獲得JSP文件后,先將JSP轉成servlet,變成xxx.java(servlet源碼),
D:\java\tomcat7.0\apache-tomcat-7.0.53\apache-tomcat-7.0.53\work\Catalina\localhost\test01\org\apache\jsp
tomcat安裝目錄 引擎 主機 項目 固定包名 這個之下就是存放著jsp變成的servlet文件.java和編譯文件.class
2、tomcat將java文件編譯成class文件
3、tomcat運行class文件,并將結果輸出到瀏覽器,
實例:
創建一個jsp。查看其轉換后的servlet代碼。
NewFile.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 hahaha 11 </body> 12 </html>
NewFile_jsp.java
1 /* 2 * Generated by the Jasper component of Apache Tomcat 3 * Version: Apache Tomcat/7.0.53 4 * Generated at: 2017-02-22 02:09:08 UTC 5 * Note: The last modified time of this file was set to 6 * the last modified time of the source file after 7 * generation to assist with modification tracking. 8 */ 9 package org.apache.jsp; 10 11 import javax.servlet.*; 12 import javax.servlet.http.*; 13 import javax.servlet.jsp.*; 14 15 public final class NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase 16 implements org.apache.jasper.runtime.JspSourceDependent { 17 18 private static final javax.servlet.jsp.JspFactory _jspxFactory=19 javax.servlet.jsp.JspFactory.getDefaultFactory(); 20 21 private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; 22 23 private javax.el.ExpressionFactory _el_expressionfactory; 24 private org.apache.tomcat.InstanceManager _jsp_instancemanager; 25 26 public java.util.Map<java.lang.String,java.lang.Long> getDependants() { 27 return _jspx_dependants; 28 } 29 30 public void _jspInit() { 31 _el_expressionfactory=_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); 32 _jsp_instancemanager=org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); 33 } 34 35 public void _jspDestroy() { 36 } 37 38 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 39 throws java.io.IOException, javax.servlet.ServletException { 40 41 final javax.servlet.jsp.PageContext pageContext; 42 javax.servlet.http.HttpSession session=null; 43 final javax.servlet.ServletContext application; 44 final javax.servlet.ServletConfig config; 45 javax.servlet.jsp.JspWriter out=null; 46 final java.lang.Object page=this; 47 javax.servlet.jsp.JspWriter _jspx_out=null; 48 javax.servlet.jsp.PageContext _jspx_page_context=null; 49 50 51 try { 52 response.setContentType("text/html; charset=UTF-8"); 53 pageContext=_jspxFactory.getPageContext(this, request, response, 54 null, true, 8192, true); 55 _jspx_page_context=pageContext; 56 application=pageContext.getServletContext(); 57 config=pageContext.getServletConfig(); 58 session=pageContext.getSession(); 59 out=pageContext.getOut(); 60 _jspx_out=out; 61 62 out.write("\r\n"); 63 out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); 64 out.write("<html>\r\n"); 65 out.write("<head>\r\n"); 66 out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n"); 67 out.write("<title>Insert title here</title>\r\n"); 68 out.write("</head>\r\n"); 69 out.write("<body>\r\n"); 70 out.write("\thahaha\r\n"); 71 out.write("</body>\r\n"); 72 out.write("</html>"); 73 } catch (java.lang.Throwable t) { 74 if (!(t instanceof javax.servlet.jsp.SkipPageException)){ 75 out=_jspx_out; 76 if (out !=null && out.getBufferSize() !=0) 77 try { out.clearBuffer(); } catch (java.io.IOException e) {} 78 if (_jspx_page_context !=null) _jspx_page_context.handlePageException(t); 79 else throw new ServletException(t); 80 } 81 } finally { 82 _jspxFactory.releasePageContext(_jspx_page_context); 83 } 84 } 85 }
可以看到public final class NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent
NewFile_jsp.java繼承自HttpJspBase。來看看HttpJspBase的源碼
HttpJspBase.java
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.jasper.runtime; 19 20 import java.io.IOException; 21 22 import javax.servlet.ServletConfig; 23 import javax.servlet.ServletException; 24 import javax.servlet.http.HttpServlet; 25 import javax.servlet.http.HttpServletRequest; 26 import javax.servlet.http.HttpServletResponse; 27 import javax.servlet.jsp.HttpJspPage; 28 29 import org.apache.jasper.compiler.Localizer; 30 31 /** 32 * This is the super class of all JSP-generated servlets. 33 * 34 * @author Anil K. Vijendran 35 */ 36 public abstract class HttpJspBase extends HttpServlet implements HttpJspPage { 37 38 private static final long serialVersionUID=1L; 39 40 protected HttpJspBase() { 41 } 42 43 @Override 44 public final void init(ServletConfig config) 45 throws ServletException 46 { 47 super.init(config); 48 jspInit(); 49 _jspInit(); 50 } 51 52 @Override 53 public String getServletInfo() { 54 return Localizer.getMessage("jsp.engine.info"); 55 } 56 57 @Override 58 public final void destroy() { 59 jspDestroy(); 60 _jspDestroy(); 61 } 62 63 /** 64 * Entry point into service. 65 */ 66 @Override 67 public final void service(HttpServletRequest request, HttpServletResponse response) 68 throws ServletException, IOException 69 { 70 _jspService(request, response); 71 } 72 73 @Override 74 public void jspInit() { 75 } 76 77 public void _jspInit() { 78 } 79 80 @Override 81 public void jspDestroy() { 82 } 83 84 protected void _jspDestroy() { 85 } 86 87 @Override 88 public abstract void _jspService(HttpServletRequest request, 89 HttpServletResponse response) 90 throws ServletException, IOException; 91 }
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage
看到了一個熟悉的類,HttpServlet,我們編寫Servlet時就是繼承自該類,這里也是繼承HttpServlet,并且HttpJspBase的源碼會發現,生命周期也是有init()方法,service()方法,destory()方法,相當于_jspService()方法就是servlet的service()方法的執行,所以說JSP也是一個servlet。
我們在JSP寫的所有html代碼,都會被轉換為servlet中的out.write(html)代碼來輸出。看圖
小總結:
對于jsp轉換成的servlet源碼,之后我們會在進行詳細分析,現在只需要知道jsp中的內容在servlet中被轉換成什么了,在哪里被轉換了即可。其中_jspService()方法的詳細內容下面會講解
注意:jsp 生成java源碼,默認第一次生成,之后直接執行,除非內容修改,具體點說,由于JSP只會在客戶端第一次請求的時候被編譯,因此第一次請求JSP時會感覺比較慢,而之后的請求因為不會編譯JSP,所以速度就快多了,如果將Tomcat保存的JSP編譯后的class文件刪除,Tomcat也會重新編譯JSP。在開發Web程序的時候經常需要修改JSP,Tomcat能夠自動檢測到JSP程序的改動,如果檢測到JSP源代碼發生了改動,Tomcat會在下次客戶端請求JSP時重新編譯JSP,而不需要重啟Tomcat,這種自動檢測功能默認是開啟的,檢測改動會消耗少量的時間,在部署web應用程序的時候可以在web.xml中將它關掉。這也就是為什么我們能夠在jsp頁面直接修改內容,而不用重新啟動服務器的原因。
因為JSP就是servlet,那么生命周期也就是跟serlvet一樣。
JSP和servlet有一點區別就在于:jsp是先部署后編譯,而servlet是先編譯后部署。
JSP模版數據:
就是JSP中的HTML代碼,它的內容給是固定的,無論程序如何運行模版數據輸出到客戶端瀏覽器時都不會發生改變,當我們創建一個JSP時,模版就已經固定了。
元素:JSP中的java部分,包括腳本(JavaScript,或者java代碼)以及JSP指令(Directive)與JSP標簽(Tag)等,元素決定著程序的流程,元素是不會顯示到瀏覽器的。這幾個都會在接下來講解到
JSP腳本:
1、使用<% 編寫java代碼 %>,中間java代碼必須遵循Java語法,
為什么能夠使用out輸出?這里就涉及到了JSP的九大內置對象了,后面會講解到,到時候回過頭來在看看這里,就會知道為什么可以使用。
來看看,jsp變為servlet時的代碼是如何編寫的。
在JSP中JSP指令(后面會講):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
這句代碼在servlet就變為了
response.setContentType("text/html; charset=UTF-8");//這句代碼的意思就是通知tomcat和瀏覽器都使用UTF-8碼表,并且發送回瀏覽器的數據類型是text/html。這是有JSP指令中畫紅色部分代碼轉變的,而指令中的pageEncoding="UTF-8"的意思是JSP轉換為Servlet時采用UTF-8碼表編碼,因為可能JSP中包含中文。
對于JSP模版數據來說,就原封不動的使用out.write()來輸出到瀏覽器
而對于JSP元素來說,就會變成普通的java代碼,因為在servlet中,就可以直接編寫java代碼。
2、使用<%=xxx %>來輸出結果
使用<%=result %>來輸出結果,servlet中就會將其轉換為out.print(result)進行輸出。輸出各種類型數據:int、double、boolean、String、Object等
3、JSP注釋
<%-- --%> :jsp注釋,
// :java單行注釋
/* */ :Java多行注釋
<!-- --> :這個注釋,會發送到瀏覽器端的源碼中顯示
注釋分別在servlet中如何顯示的?
JSP注釋不會在servlet文件中顯示,而java注釋則會,但其所有的注釋到了瀏覽器端,都不會出現在源碼中,只有<!-- -->這個注釋會到瀏覽器的網頁源碼中去
4、JSP中申明方法與屬性(全局變量) 使用<%! 方法、屬性%>
這個就不演示了,就是在JSP中編寫方法或者屬性時,使用<%! %>括起來。
5、在JSP中使用if語句,或者使用for循環,whilt循環等都可以實現,也就是編寫腳本而已。
指令用來申明JSP頁面的一些屬性,比如編碼方式,文檔類型。我們在servlet中也會申明我們使用的編碼方式和響應的文檔類型的,而JSP就是用指令來申明。上面我們也說到了一條指令,也就是page指令,
JSP指令格式:<%@ directive {attribute=value}* %>
解釋:
directive:指令名稱,例如page指令
attribute=value:緊跟指令名稱后面的就是各種屬性,以鍵值對的形式書寫
*:代表后面能跟0個或多個屬性。
例如: page指令:用來聲明JSP頁面的屬性等。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> page指令,后面跟著三個屬性,分別是language、contentType、pageEncoding。這只是其中的幾個屬性,并沒有寫全,page指令允許的屬性如下表所示
屬性名稱 取值范圍 描述
language java 解釋該JSP文件時采用的語言,一般為java語言,默認為java
extends 任何類的全名 編譯該JSP文件時繼承哪個類,JSP為Servlet,因此當指明繼承普通類時需要實現Servlet的init、destroy等方法
import 任何包名、類名 引入該JSP中用到的類、包等,import是唯一可以聲明多次的page指令屬性,一個import可以引用uogelei,中間用英文逗號隔開,
如<%@ page import="java.util.List,java.util.ArrayList"%>
session true、false 該JSP內是否內置Session對象,如果為true,則內置Session對象,可直接使用,否則反之,默認為true
autoFlush true,false 是否運行緩存,如果為true,則使用out.println()等方法輸出的字符串并不是立刻到達客戶端服務器的,而是暫時存到緩存里,緩存滿
了或者程序執行完畢或者執行out.flush()操作時才到客戶端,默認為true。
buffer none或者數字KB 指定緩存大小,當autoFlush設為true時有效,例如<%@ page buffer=10kb%>
isThreadSafe true,false 是否線程安全,如果為true,則運行多個線程同時運行該jsp程序,否則只運行一個線程,其余線程等待,默認為false
isErrorPage true,false 指定該頁面是否為錯誤顯示頁面,如果為true,則該JSP內置有一個Exception對象exception,可直接使用,否則沒有,默認為false
errorPage 某個JSP頁面的相對路徑 指明一個錯誤頁面,如果該JSP程序拋出一個未捕捉的異常,則轉到errorPage指定的頁面,errorPage指定的頁面通常
isErrorPage屬性為true,且內置的exception對象為未捕捉的異常
contentType 有效的文檔類型 客戶端瀏覽器根據該屬性判斷文檔類型,例如 HTML格式為text/html、純文本格式為text/plain、JPG圖像為image/jpeg、GIF圖 像為image/gif、WORD文檔為application/msword,該屬性常跟著charset設置編碼一起,作用是通知服務器和瀏覽器都使用同一 個碼表
info 任意字符串 指明JSP的信息,該信息可以通過Servlet.getServletInfo()方法獲取到
trimDirective Whitespaces true、false 是否去掉指令前后的空白字符,默認為false
pageEncoding UTF-8,ISO-8859-1等 指定一張碼表來對該JSP頁面進行編碼,
include指令
比較簡單,只有一種形式 <%@ include file="relativeURL"%> relativeURL:本應用程序內另一個JSP文件或者HTML文件的路徑,例如,網址內所有頁面均有一個統一風格的導航欄和頁腳版權,那么就可以使用該指令將其包含進來,
特點:include指令會將包含頁面的源代碼添加到使用include指令的頁面中來,然后編譯成class文件,而等下會講到的一個JSP行為,<jsp:include page="relativeURL">作用跟include指令一樣,但是不同的是,include行為是運行時單獨執行包含頁面,然后把執行的結果包含到本頁面來,屬于先運行后包含。
taglib指令
JSP支持標簽技術,后面會講到標簽的用法,jstl標簽庫的使用等,
作用:用來指明JSP頁面內使用的JSP標簽庫,taglib指令有兩個屬性,uri為類庫的地址,prefix為標簽的前綴
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
前面講了JSP語法,介紹了JSP頁面中的內容有哪些,分別有什么作用,就兩個東西,模塊數據和元素。其中元素有包括腳本,指令,標簽,腳本就是JSP中嵌入java代碼,指令作用就是申明頁面的屬性,那標簽是干嘛的,標簽分為JSP自帶內置的標簽,和通過taglib指令來使用JSP標簽庫,或者自定義標簽。現在我們先來講一些JSP內置的標簽。
JSP內置的標簽就被稱為JSP行為(JSP Actions)。只要書寫很少的標記代碼就能使用JSP提供的豐富功能,JSP行為其實是對常用的JSP功能的抽象與封裝,可以取代jsp腳本,讓JSP中就少一些嵌入java代碼的地方。
格式:<jsp:elements {attribute="value"}* />
jsp:標簽的前綴,說明是jsp內置的標簽,
elements:行為的名稱,
attribute=value:使用鍵值對來編寫屬性
*:能指定0個或多個屬性對
<jsp:include />行為
include行為用于運行時包含某個文件,如果被包含的文件為JSP程序,則先會執行JSP程序,然后在把執行的結果包含進來。 作用是跟include指令一樣的,唯一的區別就在于,include指令是將被包含的文件的源碼加入到了本JSP程序中,然后在進行編譯,屬于靜態包含,而include行為只是將被包含的文件的運行結果包含進自己。屬于動態包含
Java bean行為
是一組與Java Bean 相關的行為,包括useBean行為、setProperty行為、getProperty行為等
Java Bean就是普通的Java類,也被稱為POJO,只有私有的屬性與對應的getter方法和setter方法,注意其中當私有的屬性為boolean類型時,習慣上一般把getter方法寫成isXxx();而不是getXxx();
useBean行為
<jsp:useBean id="beanObject" class="className" scope="Value"> 作用:在jsp中定義一個java bean對象,
id:指明Java Bean對象的名稱,JSP中可以使用該名稱引用該Java Bean對象,相當于給new出來的對象取一個變量名,
class:Java Bean類的全名
scope:該java bean對象的作用范圍,可以寫的就四個,也就是JSP的四大作用域,page、request、session、application
page:只能在當前JSP頁面使用,如果不在JSP頁面,那么就會失效
request:這個前面學過,A頁面請求轉發到B頁面,那么使用的是同一個request,那么A,B頁面都算是request的作用域,也就是通過請求轉發的頁面都是其作 用域
session:該作用域在一個web項目下任何位置應該讀訪問的到,只要cookie不關閉,并且cookie設置 的訪問路徑為"/",
application:其實就是Servlet中的servletContext,服務器下的所有項目都能訪問到。
setProperty行為
<jsp:setProperty name="beanName" property="propertyName" value="">
對Java Bean對象進行屬性的設置
name:java bean對象的名稱,也就是在useBean行為中的id
property:對象中的屬性名,
value:要對其屬性進行賦值的值
getProperty行為
<jsp:getProperty name="beanName" property="propertyName" />
獲取JavaBean對象的某個屬性值
name:java bean 對象的名稱,也就是在useBean行為中的id
property:對象的屬性名
例子: javabean:User.java NewFile.jsp
User.java
1 package a; 2 3 public class User { 4 private int id; 5 private String username; 6 private String password; 7 public int getId() { 8 return id; 9 } 10 public void setId(int id) { 11 this.id=id; 12 } 13 public String getUsername() { 14 return username; 15 } 16 public void setUsername(String username) { 17 this.username=username; 18 } 19 public String getPassword() { 20 return password; 21 } 22 public void setPassword(String password) { 23 this.password=password; 24 } 25 26 27 }
NewFile.jsp
1 <body> 2 <!-- 創建一個新的javabean對象user,會先判斷在page作用域內是否有叫user對象的javabean,如果有則取它,如果沒有則創建新的javabean對象 --> 3 <jsp:useBean id="user" class="a.User" scope="page"></jsp:useBean> 4 <!-- 對javabean對象的username進行賦值 --> 5 <jsp:setProperty property="username" name="user" value="wu"/> 6 <!-- 獲取javabean對象的username屬性 --> 7 <jsp:getProperty property="username" name="user"/> 8 </body>
可以查看NewFile.jsp變為servlet后的源代碼,看看我們寫的javabean行為會被轉換為何種語句
這里出現了一個JSP九大內置對象中的一個,pageContext。現在簡單提一句,pageContext就是JSP頁面的管理者(上下文),其中的getAttribute(name,scope)方法是獲取指定作用域中的數據的,如果getAttribute(name)方法的話,默認是對page作用域進行操作,findAttribute(name)依次從page、request、session、application獲得內容。
在第一個紅框中,就代表中我們的useBean行為,其中進行了一次判斷,就是如果在page作用域中找不到user這個對象,那么就創建一個新的,否則就使用找到的這個user對象,
第二個紅框中,代表著我們的setProperty行為,先找到user對象,然后在對其屬性進行賦值
第三個紅框中,代表著我們的getProperty行為,也是先找到user對象,然后在獲取其屬性的值。
注意:對于javabean行為來說,有一個特點的地方,就是當請求過來的參數對應javabean的屬性時,可以為其一次性設置所有的值
<jsp:setProperty name="user" property="*" /> //設置user的所有屬性,屬性值從request中自動取得,*代表所有屬性。
<jsp:forward />行為
實現請求轉發功能,Servlet中通過request.getRequestDispatcher("someServlet").forward(request,response);而在JSP中也能夠實現相同的功能,只不過用的是<jsp:forward />行為,實際上forward行為就是對其進行了封裝。
格式:
<jsp:forward page="someServlet">
<jsp:param name="param1" value="value1"/>
<jsp:param name="param2" value="value2"/>
</jsp:forward>
page:需要跳轉到的頁面或者servlet、 <jsp:param/>參數行為,帶一些參數過去,name、value是以鍵值對的形式帶過去的
例如:
NewFile.jsp
MyServlet.java
訪問:http://localhost:8080/test01/NewFile.jsp
瀏覽器地址欄沒有改變,說明是請求轉發
NewFile_jsp.java
使用return的好處是執行完上面的轉發,就直接return,沒有必要在執行下面的代碼了,對參數使用了URLEncode進行編碼,說明該<jsp:param/>可以直接傳遞中文,但是前提是要設置request.setCharacterEncoding("UTF-8");為什么這樣做,看上面框起來中的代碼。
<jsp:directive/>行為
directive行為,就相當于JSP指令,比如<jsp:directive.page/>相當于<%@ page %>指令,等等其它指令是一樣的書寫格式。
之前那么一大段內容,就是為了講解什么是JSP,JSP中的內容是怎么樣的,到這里應該知道的差不多了, 但我們還要深入了解一些東西,我們知道JSP中的內容就只有兩種,模版數據,和元素,元素就包括了指令呀,腳本呀,標簽(行為)呀,腳本會慢慢被標簽全部代替,也就是說JSP中基本上不會嵌入Java代碼,但是我們也知道JSP會轉換為servlet,在Servlet中,輸出數據時,都需要通過response.getWrite();但是在JSP中,直接使用out對象進行輸出,為什么呢?這就是因為out為JSP的一個隱藏對象,JSP中內置了9個隱藏對象,使得JSP比Servlet使用起來更簡單,更方便,
page、config、application、request、response、session、out、exception、pageContext
page:page對象代表當前JSP頁面,是當前JSP編譯后的Servlet類的對象。相當于this。
config:標識Servlet配置,類型:ServletConfig,api跟Servlet中的ServletConfig對象是一樣的,能獲取該servlet的一些配置信息,能夠獲取ServletContext
application:標識web應用上下文,類型:ServletContext,詳情就看Servlet中的ServletContext的使用
request:請求對象, 類型:httpServletRequest
response:響應對象 類型:httpServletResponse
session:表示一次會話,在服務器端記錄用戶狀信息的技術
out:輸出響應體 類型:JspWriter
exception 表示發生異常對象,類型 Throwable,在上面我們介紹page指令中的一個errorPage屬性時就有說到他
pageContext:表示 jsp頁面上下文(jsp管理者) 類型:PageContext
標記了紅色的對象就是JSP獨有的,其他的都是Servlet中的老東西。
在這個由jsp轉換為servlet的文件中,只能看到8個內置對象,少了exception對象,因為我們在將page指令時,說過一個isErrorPage屬性,默認是false,被關閉了,所以其中并沒有exception對象。
JSP的四大作用域:page、request、session、application
這四大作用域,其實就是其九大內置對象中的四個,為什么說他們也是JSP的四大作用域呢?因為這四個對象都能存儲數據,比如request.setAttribute()注意和request.setParameter()區分開來,一個是存儲在域中的、一個是請求參數,session.setAttribute()、application其實就是SerlvetContext,自然也有setAttribute()方法。而page作用域的操作就需要依靠pageContext對象來進行了。在上面我們也有提到JSP的四大作用域,
page作用域:代表變量只能在當前頁面上生效
request:代表變量能在一次請求中生效,一次請求可能包含一個頁面,也可能包含多個頁面,比如頁面A請求轉發到頁面B
session:代表變量能在一次會話中生效,基本上就是能在web項目下都有效,session的使用也跟cookie有很大的關系。一般來說,只要瀏覽器不關閉,cookie就會一直生效,cookie生效,session的使用就不會受到影響。
application:代表變量能一個應用下(多個會話),在服務器下的多個項目之間都能夠使用。比如baidu、wenku等共享帳號。
out對象:
類型:JspWriter
jsp 輸出底層使用 response.getWriter();什么意思呢?這里就要講解一下JSP緩存和Servlet緩存了,輸出的過程是這樣的
JSP頁面轉換為Servlet后,使用的out對象是JspWriter類型的,所以是會先將要發送的數據存入JSP輸出緩存中,然后,等JSP輸出緩存滿了在自動刷新到servlet輸出緩存,等serlvet輸出緩存滿了,或者程序結束了,就會將其輸出到瀏覽器上。除非手動out.flush()。
驗證servlet輸出緩存和JSP輸出緩存和我們上面所說的是正確的。
分析:如果按沒有jsp緩存和servlet緩存的話,輸出的結果應該是aaaabbbbcccc,但是輸出的卻是bbbbaaaacccc,為什么呢?按照我們上面所說的原理進行分析,out對象是先將其輸出到JSP緩存中,所以aaaa加入了jsp緩存,而response.getWriter().print("bbbb")是直接將bbbb輸出到servlet緩存中,然后又使用out對象將cccc輸出到jsp緩存,到程序結束,servlet緩存中有bbbb,然后jsp會將緩存中的內容就刷新到servlet緩存中,serlvet就是bbbbaaaacccc了,然后到瀏覽器也就得到我們的輸出結果了。如果在12行將注釋去掉,那么輸出的結果又會是什么呢?答案就是aaaabbbbcccc,過程自行分析。
pageContext對象:重點
這個功能就比較強大了,比較牛逼,基本上什么他都有,因為是它是JSP頁面的管理者(上下文),所以JSP中的內置對象呀,它統統能夠獲得,下面介紹它的api。
1、獲得其它八大內置對象 getXxx()
pageContext.getOut(); //獲得out對象
pageContext.getApplication(); //獲得application對象
等等....
2、對作用域的屬性進行操作(四大作用域)
對默認作用域的屬性進行操作。page
pageContext.getAttribute(name); //獲得page作用域數據
pageContext.setAttribute(name,value); //給page作用域設置內容
pageContext.removeAttribute(name); //給page作用域移除內容
3、對指定作用域的屬性進行操作
getAttribute(name,scope); //獲得 指定作用域中的數據
setAttribute(name,value); //給指定作用域設置內容
removeAttribute(name ,scope) 移除指定作用域的內容(page/request/session/application)
4、提供作用域常量
PageContext.PAGE_SCOPE page
PageContext.REQUEST_SCOPE request
PageContext.SESSION_SCOPE response
PageContext.APPLICATION_SCOPE application
5、一次獲得指定名稱內容
findAttribute(name); //依次從page、request、session、application 獲得內容
response對象:
就是響應對象,、如果不了解就看看講解request和response的這一章節的內容
config對象:
類型:ServletConfig
能夠獲取servlet的初始化參數,獲取servletContext對象,獲取servletName
api詳情請看講解servlet這一章節
exception異常對象:
包含了異常的信息
使用它,必須結合page指令中的isErrorPage屬性和errorPage屬性。
exception.jsp 拋異常的一個NullPointException,并且跳轉到error.jsp錯誤顯示頁面 errorPage屬性的意思是如果發生未捕捉到的異常,將會跳轉到error.jsp頁面
error.jsp isErrorPage屬性說明該頁面是一個錯誤顯示頁面,則可以使用exception對象
訪問http://localhost:8080/test01/exception.jsp
通過上面一大堆一大堆的學習,我們應該知道這些東西
1、什么是JSP?
JSP本質上就是一個servlet,因為servlet輸出html太麻煩了,所以就有了JSP,JSP就是專門用來書寫html的,當然其中也能寫java代碼。
2、JSP的內容包括什么?
模版數據和元素。其中元素有包括腳本(java代碼)、指令(頁面屬性)、和行為(標簽,為了JSP中不嵌入那么多java代碼衍生的)
3、JSP中九大內置對象是哪九個?
九大內置對象,page、config、appliction、request、response、session、out、exception、pageContext
4、九大內置對象和servlet中對象的關系
page就是jsp轉換為servletservlet對象本身,也就是this
config -- Servlet中的servletConfig
application -- Servlet中的ServletContext
request -- Servlet中的request
response -- Servlet中的response
session -- Servlet中的session
out -- JspWriter
exception -- 異常對象
pageContext -- 表示 jsp頁面上下文(jsp管理者) 類型:PageContext,
其中pageContext對象最牛逼,有了他就擁有了天下,哈哈~
5、JSP中的四大作用域。
page、request、session、application
其中操作page域中屬性需要借助pageContext對象。
6、JSP中還有其他兩大塊內容
一個是EL表達式,很重要,
另一個是jstl標簽庫的使用,也很重要,在接下來的兩節中,就會講解到。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。