Java EE 开发技术与案例教程——第四章:JSP

目录

 

引言

JSP页面组成

JSP的运行

JSP和servlet的区别:

JSP隐含对象

EL表达式和JSTL标签

习题:

1、表示层、逻辑层、数据层分离

xml


引言

之前写了创建了那么多JSP页面,但是JSP页面到底如何编写,怎么组成,和servlet又有什么关系呢?

今天我们就来初略的学习一下JSP的内容(需要很详细的学习请看菜鸟教程

JSP页面组成

我们先来看一下的JSP页面

我们可以看到,在<%@   %>里面的是JSP标记,JSP指令用于告诉JSP容器如何处理JSP网页;JSP标记分为JSP指令标记和JSP动作标记。

JSP指令标记是用于设置页面相关属性或者执行动作的一种标记,一个指令标记中可以有多个属性,作用范围时整个页面

在jsp中的书写格式有两种

  1. <%@指令名称 属性1=“属性值” 属性2=“属性值”……%>
  2. <jsp:directive.指令属性 属性1=“属性值” 属性2=“属性值” …/>
  1. language jsp使用的脚本语言,默认java
  2. extend jsp->servlet后继承的父类
  3. import 和java的import类似,默认import了java.lang.*,javax.servlet.*,javax.servlet.jsp.*和javax.servlet.http.*,且这是唯一一个可以重复使用的属性
  4. session 是否使用session对象,session是保持连接的东西,下面有介绍
  5. buffer 输出out对象(下面讲到)的缓存区大小,none的话直接输出不缓存,以KB为单位
  6. autoFlush 缓存满的时候是否自动刷新,false的话溢出时候抛出异常
  7. isThreadSafe 默认true 指定jsp页面是否线程安全,即可以让多个客户端同时请求访问
  8. info 指定页面相关信息,可以通过调用servlet接口的getServletInfo()来获得
  9. errorPage 指定异常发生的时候,转向哪一个错误处理页面
  10. isErrorPage 是否是错误处理页面 默认false
  11. contentType 指定用于相应的jsp页面的MIME类型和字符编码,中文页面的话必须要设置<%@ page contentType="text/html; charset=gb2312" %> 或者charset=utf-8
  12. pageEncoding 指定JSP页面使用的字符编码,没有设置的话使用contentType的字符集,如果两个都没有就是ISO-8859-1 --->这使得第三章我们输入的编码是ISO,传到服务器的时候就乱码了
  13. isELIgnored 是否执行或者忽略EL表达式 true忽略 false执行
  • include用于在JSP页面中静态包含一个文件,该文件可以是JSP页面、HTML网页、文本文件或一段Java代码<%@ include file="relativeURL" %>
例4.2:include指令的使用
<%@ page contentType="text/html;charset=gb2312" %>
<html>
<head><title>欢迎你</title></head>
 <body>
 欢迎你,现在的时间是
 <%@ include file="date.jsp" %>
 </body>
 </html>
 date.jsp:
 <% out.println(new java.util.Date().toLocaleString()); %>
访问该页面,会显示当前的系统时间。
  • taglib指令允许页面使用用户自定义的标记 <%@ taglib (uri="tagLibraryURI" | tagdir="tagDir") prefix="tagPrefix" %>

JSP的动作标记是JSP的另一种标记,它利用XML语法格式来控制JSP服务器实现某种功能

JSP2.0规范中定义了20个标准的动作标记

常用的JSP动作标记有

  • <jsp:include>:在页面被请求时动态引入一个文件。     
  • <jsp:forward>:把请求转到一个新的页面。     
<jsp:forward>动作的语法格式为:
	不带参数:
	<jsp:forward page=“url”/>
	带参数:
	<jsp:forward page=“url”>{ <jsp:param …. /> }*
	</jsp:forward>
	<jsp:forward>动作只有一个属性page。
	page属性指定请求被转向的页面的相对路径,该路径是相对于当前JSP页面的URL,也可以是经过表达式计算得到的相对URL。
  • <jsp:plugin>:用于产生与客户端浏览器相关的HTML标记(<OBJECT>或<EMBED>)。     
  • <jsp:useBean>:实例化一个javaBean。     
  • <jsp:setProperty>:设置一个javaBean的属性。     
  • <jsp:getProperty>:获得一个javaBean的属性。     
  • <jsp:useBean>,<jsp:setProperty>和<jsp:getProperty>:访问JavaBean时所用。
  • <jsp:param>以“名-值对”的形式为其他标记提供附加信息,如传递参数等。它和<jsp:include>,<jsp:forward>和<jsp:plugin>一起使用。它的语法为:     <jsp:param name="name" value="value" />

在<%  %>里面的是JSP代码,实现某些需要java代码实现的功能

在<html>   </html>里的是html代码,进行网页的显示。

JSP的运行

直接将jsp放在tomcat的ROOT目录下就可以运行,打开浏览器输入http:://127.0.0.1:8080/我们写的jsp页面的名字.jsp就可以运行了

JSP和servlet的区别:

  1. servlet是一个完整的java应用程序,有类和方法,而jsp不需要类和方法的定义,比较简单。
  2. servlet需要先编译,生成的类文件部署在指定路径下,并且在配置文件(web.xml)中注册了才可以运行,而jsp直接放在相应的目录下,不需要注册(虽然第一次访问的时候是需要tomcat去编译成servlet然后提供服务的)
  3. 速度不同,servlet先编译好了所以可以直接运行,而jsp是存放的源码,只有在首次访问的时候经过编译才可以运行,但是第一次访问比较慢,之后的访问速度就正常了

JSP隐含对象

JSP为了方便程序开发和信息交互,提供了九个隐含对象,这些对象不需要声明就可以在JSP脚本和JSP表达式中使用

可分为4类:

(1)输出输入对象:

  • request对象(代表来自客户端的请求,是javax.servlet.http.HttpServletRequest接口类的实例)
  • response对象(用于响应客户端请求)
  • out对象(javax.servlet.jsp.jspWriter类的实例,用于输出,以及与缓存相关功能) 

(2)与属性作用域相关对象:       

  • pageContext对象(可以访问到本页中的所有其他对象。
  • session对象(让服务器和客户端之间一直保持连接,直到客户端主动关闭或超时(一般为30分钟)无反应才会取消这次会话,在session中可以保存关于用户的很多信息,实现同一用户在访问web站点的时候在多个页面共享信息:setAttribute()和getAttribute())
  • application对象(用于保存应用程序在服务器上的全局数据,所有用户都访问唯一的一个application对象)

(3)Servlet相关对象:         

  • page对象(JSP页面本身,它代表JSP被编译成的Servlet,可以使用它来调用Servlet类中所定义的方法,等同于Java中的this)
  • config对象 (代表当前JSP 配置信息)

(4)错误处理对象:         exception对象

EL表达式和JSTL标签

类似于JavaScript的语言,主要用于在网页上显示动态内容,替代Java脚本完成复杂功能。

习题:

1、表示层、逻辑层、数据层分离

表示层一般是可以显示在页面上的,但是页面上点击后的逻辑,一般是由逻辑层实现的,而逻辑层(至少在现在)绝大部分使用servlet进行实现的,数据层则是与数据库打交道的java类。

我们一般下了MyEclipse之后有自带jdk以及tomcat,jdk是1.6,tomcat是6版本的,我们可以使用原来的tomcat也可以使用自己下载的tomcat(详情请看Java EE 开发技术与案例教程——第一章),我由于之前使用tomcat7在工程里找不到问题,但是就是显示不了,所以新建工程使用了tomcat6(自带的)

下面先介绍一下我的工程结构

WebRoot下面的jsp全部都是用于显示的,JdbcUtils是用来和数据库打交道的,LoginServlet是处理index中login的逻辑的,RegisterServlet是用来处理注册时候的逻辑的。

首先新建一个工程,然后在index.jsp写入以下的代码

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>登录界面</title> 
 <style type="text/css">
 	body{
 	    background-image:url(images/timg.jpg);
 	    background-position:center;
            background-repeat:no-repeat;
 	  }
 	
 </style>
  </head>  
    
  <body>  
  <div style="text-align:center;margin-top:120px">  
    <h2>XQ的主页</h2>  
    <form action="LoginServlet" method="post">  
        <table style="margin-left:40%">  
             <marquee width="200"scrolldelay="250">用户登录</marquee> 
 
            <tr>  
                <td>登录名:</td>  
                <td><input name="username" type="text" size="21"></td>  
            </tr>  
            <tr>  
                <td>密码:</td>  
                <td><input name="password" type="password" size="21"></td>  
            </tr>  
        </table>   
        <input type="submit" value="登录">  
        <input type="reset" value="重置">   
    </form>  
    <br>  
    <a href="register.jsp">注册</a>  
    </div>  
  </body>  
</html>  

这里要注意的就是<form action="  " method="post">这里的action的字符串,也就是需要调用的逻辑层的文件的路径,如果登入的话会调用这个servlet的post方法,所以这里的路径需要写清楚,也就是和xml需要一致。如何一致呢,我们先看看这里的LoginServlet和其xml怎么写

(注意,我们在src下兴建了一个work4的package,同一个package下的java文件可以互相调用(因为很明显我们需要用到数据层的java类的接口)

work4中的LoginServlet.java

package work4;

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 work4.User;
import work4.UserDAO;
 
/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	     doPost(request, response);
	   }  
	
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		UserDAO userDAO=new UserDAO(); 
		User user=userDAO.login(username, password);
		if(user!=null){
			request.getRequestDispatcher("success.jsp").forward(request, response);;
		}else{
			request.getRequestDispatcher("error.jsp").forward(request, response);
		}
		
		
	}
}

其中本来在tomcat6,貌似找不到import javax.servlet.annotation.WebServlet;的定义,根据此处,import了tomcat7的jar文件,是可以不报错,找得到的。

值得关注的就是UserDAO,这个UserDAO是一个检验用户是否正确以及增加用户的类,而login方法如果用户密码出错的话就会返回一个null对象,进而跳到不同的处理jsp。

xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>

  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>work4.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>work4.RegisterServlet</servlet-class>
  </servlet>


  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet</url-pattern>
  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

因为查看用户是否正确,为了方便我们兴建了User.java类来存储数据,并且需要连接数据库,所以我们下面从源头的数据库操作数据层开始介绍

JdbcUtils.java

package work4;


import java.io.IOException;
import java.io.InputStream;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import com.mysql.jdbc.Statement;
 
 
public class JdbcUtils {
   //注册驱动的工具类
	
	private static String url = null;
	
	private static String user = null;
	
	private static String  password = null;
	
	private static String  dv = null;
	
	static{
		
	   Properties  prop = new Properties();
	   
	   
	   InputStream in = JdbcUtils.class.getResourceAsStream("a.properties");
	   
	   try {
		prop.load(in);
		
		url  = prop.getProperty("url");
		user = prop.getProperty("user");
		
		password = prop.getProperty("password");
		
		dv = prop.getProperty("driver");
		
		/*System.out.println("url:"+url);*/
		
		
		//注册驱动
		  try {
			Class.forName(dv);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
			
	}
	
	
 
	//获取连接对象
	public static  Connection getCon() throws SQLException{
		 Connection conn = null;
		 
		 conn = (Connection) DriverManager.getConnection(url, user, password);
		 
		 return  conn;
	}
	
	//关闭的方法
	public static void close(Statement statement,Connection conn){
		   if(statement !=null){
			   try {
				statement.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		   }
		   
		   if(conn !=null){
			   try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		   }
	}
		
	//关闭的方法
		public static void close(PreparedStatement preparedStatement,Connection conn,ResultSet resultSet){
			   if(preparedStatement !=null){
				   try {
					preparedStatement.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			   }
			   
			   if(conn !=null){
				   try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			   }
			   
			   if(resultSet!=null){
				   try {
					resultSet.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  }
	}
}

这个类getCon可以返回一个数据库连接的句柄 ,close方法可以关闭连接,并且有静态方法(也就是一种类一开始就会执行且只执行一遍的方法), InputStream in = JdbcUtils.class.getResourceAsStream("a.properties"); 意思就是从a.properties这个(相当于配置文件)文件中提出连接数据库的信息,然后加载驱动。然后需要连接的时候就调用getCon。

那么我们来看看a.properties

url:jdbc:mysql://localhost:3306/work1?characterEncoding=utf-8
user:root
password:12341234
driver:com.mysql.jdbc.Driver

 看来挺简单的,实现了连接数据库和关闭数据库的工程,对数据库的操作就在UserDAO.java中实现了

package work4;


import java.sql.ResultSet;
import java.sql.SQLException;
 
import work4.User;
import work4.JdbcUtils;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
 
 
public class UserDAO { 
	//数据库连接对象
	public  User  login(String username,String password) {
	   User u=null;
	   Connection connection =null;
	   PreparedStatement pstmt=null;
	   ResultSet resultSet=null;
 
	  //赋值
	  try {
		connection=JdbcUtils.getCon();
		  //静态sql语句
		String sql = "select * from user where name=? and password=?"; 
	    pstmt = (PreparedStatement) connection.prepareStatement(sql);
		pstmt.setString(1, username);
		pstmt.setString(2, password);  
		resultSet = pstmt.executeQuery();
		if(resultSet.next()){
			u=new User();
			u.setName(resultSet.getString("name"));
			u.setPassword(resultSet.getString("password"));
			System.out.println("登录成功!");
		}else{
			System.out.println("用户名或者密码错误!");
		}  
	} catch (SQLException e) {
		e.printStackTrace();
	}finally {	
	   JdbcUtils.close(pstmt, connection);	
	}
	 return u;
 
}
	public void addUser(User user) {
		Connection connection = null;
		PreparedStatement psmt = null;
		try {
			 connection = JdbcUtils.getCon();
			 
			 String sql  ="insert into user(id,name,password,role)values(?,?,?,?);";
			 
			 psmt = (PreparedStatement) connection.prepareStatement(sql);
			 
			 //运用实体对象进行参数赋值
			 psmt.setInt(1, user.getId());
			 psmt.setString(2, user.getName());
			 psmt.setString(3,user.getPassword());
			 psmt.setInt(4, user.getRole());
			 psmt.executeUpdate();		 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			 JdbcUtils.close(psmt, connection);
		}
	}	
	}

 第一个方法login首先获得连接然后设置preparedstatement的sql语句然后连接,如果说为null那么就是没有找到这样的用户数据,失败,有的话就登入成功。

然后增加用户的操作也是大同小异,最后记得要关闭资源就可以了。

同时,我们在index.jsp中看到了

    <br>  
    <a href="register.jsp">注册</a>  
    </div>  

也就是说这是一个超链接,连接到我们的ch4工程下的register(注意路径)

 register.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <title>注册界面</title>  
    <style type="text/css">
 	body{
 		background-image:url(images/tim.jpg);
 		background-position:center;
        background-repeat:no-repeat;
 	}
 	
 </style>
  </head>      
  <body>  
  <div style="text-align:center;margin-top:120px">  
    <h1 >请注册</h1>  
    <form action="http://192.168.199.196:8080/ch4/RegisterServlet" method="post">  
        <table style="margin-left:40%">  
            <caption>用户注册</caption>  
            <tr>  
                <td>ID:</td>  
                <td><input name="id" type="text" size="20"></td>  
            </tr>  
            <tr>  
                <td>登录名:</td>  
                <td><input name="name" type="text" size="20"></td>  
            </tr>  
            <tr>  
                <td>密码:</td>  
                <td><input name="password" type="password" size="20"></td>  
            </tr>  
             <tr>  
                <td>角色:</td>  
                <td><input name="role" type="text" size="20"></td>  
            </tr>  
        </table>   
        <input type="submit" value="注册">  
        <input type="reset" value="重置">   
    </form>  
    <br>  
    <a href="index.jsp">登录</a>  
    </div>  
  </body>  
</html>

 这里就是跳转到RegisterServlet.java去处理

package work4;

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 work4.User;
import work4.UserDAO;
 
/**
 * Servlet implementation class RegisterServlet
 */
@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RegisterServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			doPut(request, response);
     }  
	
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");	
		request.setCharacterEncoding("utf-8");  
         int id=Integer.valueOf(request.getParameter("id"));  
         String name=request.getParameter("name");  
         String password=request.getParameter("password");
         int role=Integer.valueOf(request.getParameter("role"));
         User user=new User();
         user.setId(id);
         user.setName(name);
         user.setPassword(password);
         user.setRole(role);
         UserDAO userDAO=new UserDAO(); 
         userDAO.addUser(user);
         System.out.println("注册成功");
         request.getRequestDispatcher("index.jsp").forward(request, response);
	}
}

注意这里的最后一句话 request.getRequestDispatcher("index.jsp").forward(request, response);

注册成功之后我们就跳回index.jsp页面了,记住不要写错了自己这个index.jsp,否则会出现错误。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值