JavaWeb11-jsp.cookie.session(1)

Jsp&cookie & session

一.jsp

1. jsp的介绍

JSP全名为Java Server Pages,中文名叫java服务器页面,本质是一个简化的Servlet设计,它是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。

它实现了Html语法中的java扩张(以 <%, %>形式)。JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。

jsp的作用:将内容的生成和显示进行分离

组成:html+java代码+jsp特殊标签

用JSP技术,Web页面开发人员可以使用HTML或者XML标识来设计和格式化最终页面,并使用JSP标识或者小脚本来生成页面上的动态内容

2. jsp的原理

jsp原理

上图描述的是一个jsp页面hello.jsp在服务器中处理的过程。

创建web工程day10,创建一个hello.jsp页面。

1.在浏览器中输入 http://localhost/day10/hello.jsp

2.服务器得到请求,会通过jsp引擎查找到hello.jsp页面

3.服务器将查找到的hello.jsp页面翻译成hello_jsp.java(其本质就是一个servlet)

4.jvm会将hello_jsp.java文件编译成hello_jsp.class

5.服务器运算hello_jsp.class文件

6.服务器生成响应结果

jsp执行原理

1.浏览器发送请求

2.服务器接受请求 处理请求

3.找到对应的jsp文件,然后将其转成java文件(hello_jsp.java)

4.jvm将java文件编译成class文件

5.服务器运行class文件,生成动态的内容,

6.将生成的内容转给服务器,服务器将响应信息返回给浏览器

7.浏览器解析

jsp对应java文件分析

上述是我们对于一个jsp运行的原理的简单分析,我们可以通过查看hello.jsp文件翻译后的.java文件来了解具体内容,生成的hello.jsp页面的java源文件存在于tomcat/work目录 下。

hello.jsp页面源代码

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>hello.jsp</title>
</head>
<body>
hello jsp
</body>
</html>

hello_jsp.java文件源代码

package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;
public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=utf-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head> \r\n");
out.write(" <title>hello.jsp</title>\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" hello jsp\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}

通过上面的内容,大家会发现在jsp页面中的所有的html代码,最终都会被流写回到浏览器端,所以我们可以在浏览器上查看到jsp页面上的html内容

3. jsp的脚本与注释

jsp中三种脚本元素

有三个基本的脚本元素,作用是使JAVA代码可以直接插入到HTML代码中

声明标签

格式:<%! int a = 1; %>

作用:声明的变量在类的成员位置上

脚本片断

格式:<% int a = 1; out.println(a); %>

作用:内容会生成在_jspService()方法中

脚本表达式(输出脚本)

格式:<%="hello " + a%>

作用:它就相当于是out.println()将内容直接输出到页面中,内容会生成在_jspService()方法中注意表达式不能以分号结尾

jsp中的注释

在jsp页面中可以使用三种注释

可以使用html中注释

<!-- html的注释 -->在java源码和html源文件中都有

可以对jsp脚本内容使用java注释

//单行注释 /* 多行注释 */ / ** 文档注释 */ 在java源码中有,在html源文件中没有

可以使用jsp注释(推荐)

<%-- jsp注释 --%>在Java源码和html源文件中都没有

4. jsp与servlet的结合使用

Jsp实现登录案例

把昨天的登录操作使用jsp实现一下,流程稍稍改变一下:

创建数据库与表

CREATE DATABASE day10;
USE day10;
CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20),
PASSWORD VARCHAR(20),
email VARCHAR(50),
sex VARCHAR(20),
telephone VARCHAR(20),
introduce VARCHAR(200)
)
INSERT INTO USER VALUES(NULL,"tom","123","tom@itcast.cn","男","13888888888","good boy");

导入mysql驱动jar包

创建JdbcUtils工具类及jdbc.properties配置文件

创建User类
public class User {
private int id;
private String username;
private String password;
private String email;
private String sex;
private String telephone;
private String introduce;

get/set方法省略

login.jsp页面

<%@ 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>
<%=request.getAttribute("loginmsg") %>
<form action="/day10/login" method="post">
USERNAME:<input type="text" name="username"><br>
PASSWORD:<input type="password" name="password"><br>
<input type="submit" value="登陆">
</form>
</body>
</html>

LoginServlet类

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.获取请求参数 username password
String username = request.getParameter("username");
String password = request.getParameter("password");
// 2.调用UserOperation类中的login方法
UserOperation uo = new UserOperation();
User user = uo.login(username, password);
//3.判断user是否为null来确定是否登陆成功
if(user==null){
//登陆失败,请求转发到login.jsp页面
request.setAttribute("loginmsg", "登陆失败");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}else{
//登陆成功,重定向到success.jsp
response.sendRedirect("/day10/success.jsp");
}
}
UserOperation操作类
public User login(String username, String password) {
User user = null;
// 1.定义sql语句
String sql = "select * from user where username=? and password=?";
// 2.查找数据库操作
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
// 2.1获取Connection对象
con = JdbcUtils.getConnection();
// 2.2 获取执行sql语句的PreparedStatement对象
pst = con.prepareStatement(sql);
// 2.3对占位符赋值
pst.setString(1, username);
pst.setString(2, password);
// 2.4执行sql获取ResultSet
rs = pst.executeQuery();
// 2.5操作ResultSet
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setEmail(rs.getString("email"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setSex(rs.getString("sex"));
user.setTelephone(rs.getString("telephone"));
user.setIntroduce(rs.getString("introduce"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 2.6关闭资源
JdbcUtils.closeResource(con,pst,rs);
}
return user;
}

success.jsp页面

<%@ 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>
<h1>登陆成功</h1>
</body>
</html>

首次进入登录页面的时候发现最上面显示为null,需要先判断一下loginmsg是否为空,在输出.这段代码用el表达式(明天讲)实现起来特别简单.

EL 全名为Expression Language

语法:${标识符}

常用功能:获取各种域中存储的数据

jsp写法:<%=request.getAttribute("loginmsg");>

el写法:${requestScope.loginmsg}

修改之后的login.jsp

<%@ 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>
${requestScope.loginmsg}
<form action="/day10/login" method="post">
USERNAME:<input type="text" name="username"><br>
PASSWORD:<input type="password" name="password"><br>
<input type="submit" value="登陆">
</form>
</body>
</html>

二.会话技术

会话的介绍:

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话

会话的作用:

每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据。

例如:用户点击超链接通过一个servlet购买了一个商品,程序应该保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户商品为用户结帐

会话技术会为两类

Cookie

Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

Session

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

三.cookie

1. cookie的介绍

什么是cookie

Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。

Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,对于JSP而言也可以直接写入jsessionid,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等,服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

cookie与http

cookie与http协议关系

Cookie是Http协议制定的,并不是Java语言独有的,PHT、.NET中也使用了cookie技术,因此只要是和HTTP协议相关,那么就可以使用cookie技术。

我们知道cookie是服务器创建的一个键值对,并保存在浏览器端。那么服务器是如何将cookie发送给浏览器的呢?

在服务器端先创建cookie,如 Cookie cookie=new Cookie(String name,String value),其中Cookie可以在javaeeAPI中查到的,详情可参考java_ee API。然后再通过response对象将cookie信息作为响应头发送到浏览器端。我们可以通过HttpWatch抓包工具查看响应信息,可以发现cookie是基于一个Set-Cookie响应头工作的,由于Set-Cookie响应头可以有多个,所以我们可以通过response.addHeader(String name,String value)方法发送Set-Cookie响应头,例如,有两个cookie,分别为one=aaa,two=bbb,其中one、two是cookie的名称,aaa、bbb是cookie的值。发送响应头如下所示:

response.addHeader(“Set-Cookie”,”one=aaa”);

response.addHeader(“Set-Cookie”,”two=bbb”);

当浏览器再次访问服务器时,会将cookie送还给服务器。那么浏览器是如何将cookie带给服务器的呢?其实通过Cookie请求头传递过去的。请求头Cookie与响应头Set-Cookie有区别,多个cookie对应多个Set-Cookie响应头,但是只对应一个Cookie请求头,格式为:Cookie:one=aaa; two=bbb。即多个cookie之间用分号和空格隔开。

需要注意的是:cookie是不能跨浏览器的。例如,张三首先使用IE浏览器访问服务器,服务器发送了一个cookie,这个cookie只会保存在IE浏览器,如果再使用火狐浏览器访问服务器,服务器会再发送一个cookie个火狐浏览器,在火狐浏览器中不能获取IE浏览器中的cookie,同理IE浏览器也获取不到火狐浏览器中的cookie。

原文发布于微信公众号 - Java帮帮(javahelp)

原文发表时间:2017-01-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发技术

spring集成mybatis实现mysql读写分离

       在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,...

1571
来自专栏一个爱瞎折腾的程序猿

asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档

开局一张图,然后开始编,一些基本的asp.net core东西就不再赘述,本文只对Swashbuckle.AspNetCore的几个使用要点进行描述。

1771
来自专栏好好学java的技术栈

看了这篇文章,mybatis配置你肯定会了

MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。

993
来自专栏SDNLAB

OpenDaylight Lithium版本简单应用及流表操作指南

OpenDaylight(以下简写为ODL)的Lithium(锂)版本的最新版Lithium-SR2已经与2015年10月8日发布,具体详情可参考ODL官网。L...

5028
来自专栏惨绿少年

磁盘管理 之 parted命令添加swap,文件系统

第1章 磁盘管理 1.1 必须要了解的。 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb ;   ...

2790
来自专栏冷冷

【springboot】 springboot 整合mybatis-plus

springboot整和mybatis-plus 整合步骤 1.pom.xml 添加mp依赖 <!-- mybatis-plus begin --> <depe...

4869
来自专栏james大数据架构

资源等待类型sys.dm_os_wait_stats

动态管理视图  sys.dm_os_wait_stats  返回执行的线程所遇到的所有等待的相关信息。可以使用该聚合视图来诊断 SQL Server 以及特定查...

2297
来自专栏岑玉海

Hadoop源码系列(一)FairScheduler申请和分配container的过程

1、如何申请资源 1.1 如何启动AM并申请资源 1.1.1 如何启动AM val yarnClient = YarnClient.createYarnClie...

4514
来自专栏我的博客

极光推送案例

参考:http://docs.jpush.io/server/php_sdk/ Thinkphp推送类(需要下载vendor) push() ...

4458
来自专栏魏琼东

分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

     在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于...

1180

扫码关注云+社区

领取腾讯云代金券