如图:php
JSP全名为Java Server Pages,其根本是一个简化的Servlet设计,他实现了再Java当中使用HTML标签。JSP是一种动态网页技术标准也是JavaEE的标准。JSP与Servlet同样,是在服务器端执行的。css
JSP实际上就是Servlet。JSP这门技术的最大的特色在于:写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术容许在页面中嵌套java代码,为用户提供动态数据。html
Servlet:服务器端的小应用程序。适合编写Java逻辑代码,若是编写网页内容------->费时费力,太苦java
HTML:静态内容web
jsp(java server pages):适合编写输出动态内容,但不适合编写Java逻辑数据库
JSP编程
Servlet数组
jsp=html+java脚本+jsp标签(指令)浏览器
jsp中无需建立便可使用的对象一共有9个,称为九大内置对象。缓存
3种java脚本:
jsp实际上是一种特殊的Servlet
一、IE浏览器在访问JSP页面时,Web服务器是如何调用并执行一个jsp页面的?(Servlet)
二、Web服务器在执行jsp页面时,是如何把Jsp页面中的html排版标签发送到客户端的?
三、Jsp页面中的java代码服务器是如何执行的?
四、Web服务器在调用jsp时,会给jsp提供一些什么java对象(内置对象)?
Servlet:控制器。重点编写java代码逻辑。(获取表单数据、处理业务逻辑、分发转向)
JSP:代码显示模板。重点在于显示数据。(为何显示数据不直接用.html文件呢?由于.jsp文件中能够插入java代码显示回显消息,简言之,jsp功能更强大)
JSP的模版元素:简言之就是网页的静态内容
例如:html标签和普通文本。
JSP的脚本:
<%= 2 + 3 %> 等价于out.print(2 + 3);
注释:
特色:安全,省流量
特色:不安全,费流量
JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其他部分。
在JSP 2.0规范中共定义了三个指令:
例如:
做用:
属性:
<%@ page import="java.util.Date, java.util.List" %>
或者:
<%@ page import="java.util.Date" %>
<%@ page import="java.util.List" %>
import java.lang.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
若是写"/"则表明当前应用的目录下,绝对路径。
若是不写"/"则表明相对路径。
例如:<%@ page pageEncoding="gbk" %>
例如:${1+1} 等价于out.print(1+1);
include指令用于引入其它JSP页面,若是使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。因此include指令引入一般也称之为静态引入。
<%@ include file="/include/header.jsp" %>
<jsp:include page="/include/header.jsp"></jsp:include>
二者的区别:转译(翻译)的时间段不一样
使用原则:能用静的就不用动的。缘由之一是:能够省略一些代码的书写。
JSP API容许用户自定义标签,一个自定义标签库就是自定义标签的集合。
Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
Taglib指令的语法:
<%@ taglib uri="uri" prefix="prefixOfTag" %> 复制代码
uri属性肯定标签库的位置,prefix属性指定标签库的前缀。
等价的XML语法:
<jsp:directive.taglib uri="uri" prefix="prefixOfTag" /> 复制代码
做用:在JSP页面中导入JSTL标签库。替换jsp中的java代码片断。
<%@ taglib uri=" java.sun.com/jsp/jstl/co…" prefix="c" %>
prefix:前缀(至关于从新给uri起个名字)
示例:
<%   if (5 > 3) {   out.print(5);   } %> <%-- 上下二种方式是等价的 --%> <c:if test="${5>3}">   aaa </c:if> 复制代码
下面的这种方式很好用!后面慢慢体会。
使用标签的形式来表示一段java代码。
JSP行为标签使用XML语法结构来控制servlet引擎。它可以动态插入一个文件,重用JavaBean组件,引导用户去另外一个页面,为Java插件产生相关的HTML等等。
行为标签只有一种语法格式,它严格遵照XML标准:
<jsp:action_name attribute="value" /> 复制代码
行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签:
指在JSP的<%=%> 和<% %>中能够直接使用的对象,服务器给咱们建立好的对象,直接拿过来用就好了。
例如:
<%=request.getParameter("name") %> <%    Student stu = new Student();    stu.setName("tom");   out.print(stu.getName());    // request.getRequestDispatcher("/7.jsp").forward(request, response); %> 复制代码
request对象是javax.servlet.http.HttpServletRequest类的实例。每当客户端请求一个页面时,JSP引擎就会产生一个新的对象来表明这个请求。
request对象提供了一系列方法来获取HTTP信息头,包括表单数据,cookies,HTTP方法等等。
接下来将会介绍一些在JSP编程中经常使用的获取HTTP信息头的方法。详细内容请见下表:
在这个例子中,咱们会使用HttpServletRequest类的getHeaderNames()方法来读取HTTP信息头。这个方法以枚举的形式返回当前HTTP请求的头信息。
获取Enumeration对象后,用标准的方式来遍历Enumeration对象,用hasMoreElements()方法来肯定何时中止,用nextElement()方法来得到每一个参数的名字
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.io.*,java.util.*" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h2>HTTP 头部请求实例</h2> <table width="100%" border="1" align="center"> <tr bgcolor="#949494"> <th>Header Name</th><th>Header Value(s)</th> </tr> <% Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) { String paramName = (String)headerNames.nextElement(); out.print("<tr><td>" + paramName + "</td>\n"); String paramValue = request.getHeader(paramName); out.println("<td> " + paramValue + "</td></tr>\n"); } %> </table> </body> </html> 复制代码
response 对象是 javax.servlet.http.HttpServletResponse 类的一个实例。就像服务器会建立request对象同样,它也会建立一个客户端响应。
response对象定义了处理建立HTTP信息头的接口。经过使用这个对象,开发者们能够添加新的cookie或时间戳,还有HTTP状态码等等。
下表列出了用来设置HTTP响应头的方法,这些方法由HttpServletResponse 类提供:
接下来的例子使用setIntHeader()方法和setRefreshHeader()方法来模拟一个数字时钟:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.io.*,java.util.*" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body> <h2>自动刷新实例</h2> <% // 设置每隔5秒自动刷新 response.setIntHeader("Refresh", 5); // 获取当前时间 Calendar calendar = new GregorianCalendar(); String am_pm; int hour = calendar.get(Calendar.HOUR); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); if(calendar.get(Calendar.AM_PM) == 0) am_pm = "AM"; else am_pm = "PM"; String CT = hour+":"+ minute +":"+ second +" "+ am_pm; out.println("当前时间: " + CT + "\n"); %> </body> </html> 复制代码
咱们在浏览网页的时候,常常须要向服务器提交信息,并让后台程序处理。浏览器中使用 GET 和 POST 方法向服务器提交数据。
GET方法将请求的编码信息添加在网址后面,网址与编码信息经过"?"号分隔。以下所示:
www.runoob.com/hello?key1=… GET方法是浏览器默认传递参数的方法,一些敏感信息,如密码等建议不使用GET方法。
用get时,传输数据的大小有限制 (注意不是参数的个数有限制),最大为1024字节。
一些敏感信息,如密码等咱们能够经过POST方法传递,POST提交数据是隐式的。
POST提交数据是不可见的,GET是经过在url里面传递的(能够看一下你浏览器的地址栏)。
JSP使用getParameter()来得到传递的参数,getInputStream()方法用来处理客户端的二进制数据流的请求。
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <title>表单信息</title> </head> <body> <form action="Demo1.jsp" method="post"> <input type="text" name="name"/><br> <input type="text" name="url"/><br> <input type="checkbox" name="mao" checked="checked"/>猫<br> <input type="checkbox" name="gou"/>狗<br> <input type="checkbox" name="ji" checked="checked"/>鸡<br> <input type="checkbox" name="ya"/>鸭<br> <input type="submit" value="提交"> </form> </body> </html> 复制代码
<%@ page import="java.util.Enumeration" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP</title> </head> <body> <h1>读取参数信息</h1> <table align="center" border="1" width="100%"> <tr bgcolor="#f0f8ff"> <th>参数名</th> <th>对应值</th> </tr> <% Enumeration<String> parameterNames = request.getParameterNames(); request.setCharacterEncoding("utf-8"); while (parameterNames.hasMoreElements()){ String name = parameterNames.nextElement(); out.println("<tr><td>"+name+"</td>\n"); String url = request.getParameter(name); out.println("<td>"+url+"</td></tr>\n"); } %> </table> <% %> </body> </html> 复制代码
PageContext:pageConext
存放的数据仅在当前页面有效。开发时使用较少。当前页面存放数据用表单标签中的 ,且该存值方式用户看不到。
ServletRequest: request
存放的数据在一次请求(转发:能够传数据)内有效。使用很是多。
HttpSession: session
存放的数据在一次会话(屡次请求)中有效。使用的比较多。例如:存放用户的登陆信息、购物车功能。
ServletContext: application
存放的数据在整个应用范围内都有效。由于范围太大,应尽可能少用。用于统计在线人数。
会话可简单理解为:用户开一个浏览器,点击多个超连接,访问服务器多个web资源,而后关闭浏览器,整个过程称之为一个会话。
每一个用户在使用浏览器与服务器进行会话的过程当中,不可避免各自会产生一些数据,程序要想办法为每一个用户保存这些数据。
例如:用户点击超连接经过一个servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结账servlet时,结账servlet能够获得用户购买的商品为用户结账。
思考:用户购买的商品保存在request或servletContext中行不行?答:不行。
保存会话数据的两种技术:
当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
因为session为用户浏览器独享,因此用户在访问服务器的web资源时,能够把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
无状态是指,当浏览器发送请求给服务器时,服务器响应客户端请求。可是当同一个浏览器再次发送请求给服务器时,服务器并不知道它就是刚才那个浏览器。简单来讲,就是服务器不会去记得你,因此就是无状态协议。
Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息。在servlet技术基础上,JSP显然可以提供对HTTP cookie的支持。
一般有三个步骤来识别回头客:
JSP Cookie 处理须要对中文进行编码与解码,方法以下:
String str = java.net.URLEncoder.encode("中文","UTF-8"); //编码 String str = java.net.URLDecoder.decode("编码后的字符串","UTF-8"); // 解码 复制代码
使用JSP设置cookie包含三个步骤:
Cookie cookie = new Cookie("key","value"); 复制代码
请务必牢记,名称和值中都不能包含空格或者以下的字符:
[ ] ( ) = , " / ? @ : ; 复制代码
cookie.setMaxAge(60*60*24); 复制代码
response.addCookie(cookie); 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>表单提交</title> </head> <body> <form action="CookieDemo.jsp" method=GET> 站点名: <input type="text" name="name"> <br /> 网址: <input type="text" name="url" /> <input type="submit" value="提交" /> </form> </body> </html> 复制代码
<%@ page import="java.net.URLEncoder" %> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %> <% // 编码,解决中文乱码 String str = URLEncoder.encode(request.getParameter("name"),"utf-8"); // 设置 name 和 url cookie Cookie name = new Cookie("name", str); Cookie url = new Cookie("url", request.getParameter("url")); // 设置cookie过时时间为24小时。 name.setMaxAge(60*60*24); url.setMaxAge(60*60*24); // 在响应头部添加cookie response.addCookie( name ); response.addCookie( url ); %> <html> <head> <title>设置 Cookie</title> </head> <body> <h1>设置 Cookie</h1> <ul> <li><p><b>网站名:</b> <%= request.getParameter("name")%> </p></li> <li><p><b>网址:</b> <%= request.getParameter("url")%> </p></li> </ul> </body> </html> 复制代码
想要读取cookie,您就须要调用request.getCookies()方法来得到一个javax.servlet.http.Cookie对象的数组,而后遍历这个数组,使用getName()方法和getValue()方法来获取每个cookie的名称和值。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.net.*" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>获取 Cookie</title> </head> <body> <% Cookie cookie = null; Cookie[] cookies = null; // 获取cookies的数据,是一个数组 cookies = request.getCookies(); if( cookies != null ){ out.println("<h2> 查找 Cookie 名与值</h2>"); for (int i = 0; i < cookies.length; i++){ cookie = cookies[i]; out.print("参数名 : " + cookie.getName()); out.print("<br>"); out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>"); out.print("------------------------------------<br>"); } }else{ out.println("<h2>没有发现 Cookie</h2>"); } %> </body> </html> 复制代码
删除cookie很是简单。若是您想要删除一个cookie,按照下面给的步骤来作就好了:
下面的程序删除一个名为"name"的cookie,当您第二次运行CookieDemo2.jsp时,name 将会为 null。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.net.*" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>获取 Cookie</title> </head> <body> <% Cookie cookie = null; Cookie[] cookies = null; // 获取当前域名下的cookies,是一个数组 cookies = request.getCookies(); if( cookies != null ){ out.println("<h2> 查找 Cookie 名与值</h2>"); for (int i = 0; i < cookies.length; i++){ cookie = cookies[i]; if((cookie.getName( )).compareTo("name") == 0 ){ cookie.setMaxAge(0); response.addCookie(cookie); out.print("删除 Cookie: " + cookie.getName( ) + "<br/>"); } out.print("参数名 : " + cookie.getName()); out.print("<br>"); out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>"); out.print("------------------------------------<br>"); } }else{ out.println("<h2>没有发现 Cookie</h2>"); } %> </body> </html> 复制代码
HttpSession是有JavaWeb提供的,用来会话跟踪的类,session是服务器对象,保存在服务器端;
HttpSession是Servlet三大域对象之一(request、session、application),因此它也有setAttribute()、getAttribute()、removeAttribute()方法;
HttpSession底层依赖Cookie,或是URL重写。
会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束; 会话:一个用户对服务器的屡次连贯性请求,所谓连贯性请求,就是该用户屡次请求中间没有关闭浏览器。
服务器会为每一个客户端建立一个session对象,session就比如客户在服务器端的帐户,它们被服务器保存到一个Map中,这个Map被称为session缓存。
Servlet中获得session对象:HttpSession session = request.getSession();
JSP中获得session对象:session是jsp内置对象之下,不用建立就能够直接使用。
void setAttribute(String name,Object val); Object getAttribute(String name); void removeAttribute(String name); 复制代码
案例相关页面和Servlet:
login.jsp:登陆页面
LoginSuccess.jsp:只有登陆成功才能访问的页面
LoginServlet:校验用户是否登陆成功
各页面和Servlet内容:
login.jsp:提供登陆表单,提交表单请求LoginServlet
LoginServlet:获取请求参数,校验用户是否登陆成功
失败:保存错误信息到request域,转发到login.jsp,在login.jsp中显示request域中的错误信息;
成功:保存用户信息到session域中,重定向到LoginSuccess.jsp页面,显示session域中的用户信息。
LoginSuccess.jsp:从session域获取用户信息,若是不存在,显示“您尚未登陆”,存在则显示用户信息;
只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一块儿存在,那么用户访问LoginSuccess.jsp就会经过
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <title>登陆页面</title> </head> <body> <% //获取cookie的值 String name = ""; String pwd = ""; Cookie[] cs = request.getCookies(); if(cs!=null){ for(Cookie c : cs){ if("username".equals(c.getName())){ name = c.getValue(); } if("pwd".equals(c.getName())){ pwd = c.getValue(); } } } %> <% //获取request信息 String message=""; String mess = (String)request.getAttribute("message"); if(mess!=null){ message = mess; } %> <h1>用户登陆</h1> <span color="red"><%=message %></span> <form action="/LoginServlet" method="post"> <p> 帐号:<input type="text" name="username" value="<%=name %>" /> </p> <p> 密码:<input type="password" name="pwd" value="<%=pwd %>" /> </p> <p> <input type="submit" value="登陆"> </p> </form> </body> </html> 复制代码
LoginServlet.java
package com.demo.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置请求的字符编码 request.setCharacterEncoding("utf-8"); //接收客户端请求 String username = request.getParameter("username"); String pwd = request.getParameter("pwd"); //判断是否登陆成功 if("admin".equals(username) && "1234".equals(pwd)){ //登陆成功,把信息保存到cookie中 Cookie c1 = new Cookie("username",username); Cookie c2 = new Cookie("pwd",pwd); c1.setMaxAge(60*60*24); c2.setMaxAge(60*60*24); response.addCookie(c1); response.addCookie(c2); //登陆成功,保存用户名到session中,并重定向到LoginSuccess.jsp HttpSession session = request.getSession(); session.setAttribute("username", username); response.sendRedirect("/LoginSuccess.jsp"); }else{ //转发给客户端“登陆失败” request.setAttribute("message", "用户信息错误,请从新登陆"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } } 复制代码
LoginSuccess.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <title>登陆成功</title> </head> <body> <% //获取session信息 String name = (String)session.getAttribute("username"); if(name==null){ //session不存在,转发到登陆页面,并提示信息 request.setAttribute("message", "您尚未登陆,不能访问页面"); request.getRequestDispatcher("/login.jsp").forward(request, response); //重定向到login.jsp,不会显示request提示的信息 //response.sendRedirect("/login/login.jsp"); return; } %> <h1>登陆成功</h1> 你好<%=name %>,欢迎登陆! </body> </html> 复制代码
一个网络服务器能够发送一个隐藏的HTML表单域和一个惟一的session ID,就像下面这样:
<input type="hidden" name="sessionid" value="12345"> 复制代码
这个条目意味着,当表单被提交时,指定的名称和值将会自动包含在GET或POST数据中。每当浏览器发送一个请求,session_id的值就能够用来保存不一样浏览器的轨迹。
这种方式多是一种有效的方式,但点击标签中的超连接时不会产生表单提交事件,所以隐藏表单域也不支持通用会话跟踪。
您能够在每一个URL后面添加一些额外的数据来区分会话,服务器可以根据这些数据来关联session标识符。
举例来讲,w3cschool.cc/file.htm;se… session标识符为sessionid=12345,服务器能够用这个数据来识别客户端。
相比而言,重写URL是更好的方式来,就算浏览器不支持cookies也能工做,但缺点是您必须为每一个URL动态指定session ID,就算这是个简单的HTML页面。
除了以上几种方法外,JSP利用servlet提供的HttpSession接口来识别一个用户,存储这个用户的全部访问信息。
默认状况下,JSP容许会话跟踪,一个新的HttpSession对象将会自动地为新的客户端实例化。禁止会话跟踪须要显式地关掉它,经过将page指令中session属性值设为false来实现,就像下面这样:
<%@ page session="false" %> 复制代码
JSP引擎将隐含的session对象暴露给开发者。因为提供了session对象,开发者就能够方便地存储或检索数据。
下表列出了session对象的一些重要方法:
服务器不会立刻给你建立session,在第一次获取session时,即reques.getSession()方法执行时,才会建立session。
获取Cookie中的JSESSIONID: