Java Server Pages
本质上就是一个jsp,是运行在服务器的servlet
作用:能够在html中嵌套java代码
牛逼描述:将内容的生成和信息的展示进行分离;
备注:用Eclipse写代码之前,要手动调整eclipse的编码格式:
JSP的组成部分:
1)html代码(主体部分应该都是html代码)
2)java代码(有特定的脚本标识)
3)jsp特有的内容;
jsp的执行流程:
-1) 第一次访问一个jsp页面如index.jsp的时候,服务器收到请求,jspservlet会去查找对应的jsp文件
-2) 找到之后,服务器会将这个jsp文件JspTest01.jsp转换成java文件(要找这个文件,在服务器目录下的work下找:JspTest01_jsp.java)
-3) 服务器编译java文件,生成.class文件(JspTest01_jsp.class)
-4) 服务器运行class文件,生成动态的内容
-5) 服务器将生成的动态内容,返回给浏览器
jsp脚本:
1)<%……%> :编写java代码的
在servlet的service方法中生成java程序代码片段;
<%
//编写java代码,会被翻译到servlet的service中
out.print(“hello jsp
”)
%>
理解:
<body>
<div>
<%
out.print("this is jspTest01!<hr/>");
for(int i=0;i<5;i++){
out.print("i : "+i);
%>
<hr/>
<%
}
%>
</div>
</body>
上述写法就等同于:
<div>
<%
out.print("this is jspTest01!<hr/>");
for(int i=0;i<5;i++){
out.print("i : "+i+"<hr/>");
}
%>
</div>
2)<%= …… %>向页面上输出内容
注意:不需要添加分号结尾
翻译到servlet中的service方法,相当于是调用了out.print();
<%="hello world! hello java service page!<hr/>"
%>
3)<%! …… %> 定义成员,会被翻译到类的成员上。
jsp文件翻译出来就是一个java文件,其实就是一个类,所以这样定义出来的成员属性或者成员函数都在这个类的成员上。
<%!
private int j = 100;
public void testabc(){
}
%>
<%! int i = 0;%>
<%=i+"<br/>" %>
<%=j %>
<%! int j=100; %>
上述方法的不同:
<%……%> 编译出来在类的service函数中
<%! …… %> 编译出来在类的成员中;
上次两种方法的区别:编译出来的位置不同。
关于:jsp脚本注释
<%-- --%>
加注释:ctrl+shift+/
翻译的时候,jsp注释部分不会翻译到java中,而其他的翻译内容,如html的翻译内容都会被翻译。
如下例所示:
而下述注释方式是会被翻译的:
注释小结:
1)html注释
会在html源码和java源码中存在
2)java注释
只会在java的源码中存在
3)jsp注释
格式: <%– 注释内容 –%>
不会出现在java源码中和html源码中
jsp指令:
作用:声明当前页面的一些属性和行为
<%@ 指令名称 属性 = 值%>
注意:
指令的位置随意,一般放在jsp最上面
指令其实是可以出现多次的
分类:
1)page指令:声明当前页面的一些属性和行为
2)include指令:包含(静态包含)
3)taglib指令:导入标签库
<%@ page language=”java” contentType=”text/html; charset=UTF-8”
pageEncoding=”UTF-8” %>
<%@ 指令名称 属性 = 值%>
声明当前页面的一些属性和行为,一般在jsp文档的最开头
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
1) page指令:主要是声明当前页面的一些属性。
language:声明当前页面嵌入的语言,如java
pageEncoding:声明当前文件所使用的编码
contentType:设置当前文件mime类型,指定文件生成响应的时候所使用的类型和编码;通常建议上述两个编码(contentType和pageEncoding)保持一致;
a)两者同时出现的时候,各自使用各自指定的编码;
b)两者出现一个的时候,两者默认使用指定的编码;
c)两者都不出现的 时候,使用默认的编码(不修改的时候是is0-8859-1)
inport:导包,主要是用来导入jar包的。声明当前页面所需要的jar包
buffer:设置页面缓冲区的大小的。默认是8kb-8192
autoFlush:默认为true,设置是否自动刷新缓冲区
extends:设置当前jsp继承哪个类,但必须是一个servlet
errorPage:用来设置如果当前页面出现错误的时候转发到哪一个页面上去。内部用的请求转发,地址栏不会改变的。
session:用来设置当前页面是否可以直接使用session对象
isELIgnored:是否忽略EL表达式;默认false就好
isErrorPage:默认为false;声明当前页面是否是一个错误页面,声明之后可以用一个内置对象Exception;(设置当前页面是是否是一个专门用于显示错误信息的页面,若是则可以使用exception内置对象)
2)include指令:
作用:将被包含资源的所有内容复制过来,一并编译运行。
路径从工程下面开始写即可:
将多个jsp页面编译到一个java文件中编译执行
<%@ include file=”/static_include/1.jsp” %>
<%@ include file=”/static_include/2.jsp” %>
查看服务器文件夹下的work文件夹内发现:只有一个jsp文件
即 静态包含:将多个jsp页面翻译到一个jsp里面即可;
作用:提高复用性
3)taglib指令:
导入标签库;在使用EL表达式的时候使用。
jsp中内置对象和域对象:
内置对象:在jsp页面中可以直接使用的对象成为内置对象。
内置对象9个(9个隐式对象):
request:真实对象是httpServltRequest
response:真实对象是httpServletResponse
session:真实对象是httpSession
application: servletContext;存放共享数据
out : JspWriter ,和printWriter差不多,但是有区别(依赖printWriter实现的)
config:servletConfig,封装一些配置
exception:Throwable,只有当前jsp已经声明isErrorPage才会出现的。
page:Servlet(this),代表当前页面,代表当前servlet
pageContext: PageContext代表当前页面的上下文;作用范围只在当前页面;主要作用是获取其他内置对象,在当前页面内共享数据;
pageContext:
1) 最重要:findAttribute(key):从域对象中查询数据。有XXXAttribute方法的就是域对象,底层是一个map,如果找到,就立即返回,停止向后继续查找。EL表达式依赖的原理;
pageContext:当前页面
request:当前请求
session:当前会话
application:当前web应用
找寻过程从小到大,就是从上面的四个上面从上到大的寻找;
2)操作其他域对象的内容
setAttribute(key,value,scope)
四大域对象:
pageContext 当前页面
主要是当前的页面的上下文
request 当前请求
创建: 请求达到的时候
销毁: 响应生成的时候
作用: 可以在一次请求中传递参数
session 当前会话
创建: 第一次调用request.getSession()
销毁: 1.30分钟超时, 2.调用invalidate(). 3.服务器非正常关闭
作用: 存放用户私有数据
application 当前工程
创建: 服务器启动的时候/工程被添加到服务器中的时候
销毁: 服务器关闭的时候/工程被移除的时候
作用: 存放工程内需要共享的数据
都有xxxAttribute的属性操作
jsp动作标签:
foward:在jsp页面中完成请求转发
include:动态包含:
动态的将jsp页面的执行结果包含进来。
每一个jsp文件都是单独翻译成一个java文件,
(静态包含是将所有的jsp文件翻译到一个文件中再执行。)
<jsp:include page="/jsp/Test01.jsp"></jsp:include>
<jsp:include page="/jsp/Test02.jsp"></jsp:include>
<jsp:include page="/jsp/Test03.jsp"></jsp:include>
查看服务器中的work文件夹,可以看出动态包含是分别编译,然后合成一个jsp文件的
前提:100个jsp页面
动态包含和静态包含谁好:
修改100个页面中其中的某个
看需求,看最后变动程度;
JSPWriter和PrinterWriter的区别:
JSPWriter是依赖于PrinterWriter实现的;
JSPWriter缓存中的数据是要刷新到PrinterWriter缓存中去,然后再输出的。
案例: 商品信息展示
jsp展示页面:ShowGoods.jsp
<%@page import="com.itheima.domain.Product"%>
<%@page import="java.util.List"%>
<%@ 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=UTF-8">
<title>展示所有商品</title>
</head>
<body>
<%-- 如果发生异常情况 --%>
<%=request.getAttribute("msg") == null ? "":request.getAttribute("msg")+"<br>" %>
<table border="1px" align="center" style="background-color:green" >
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品描述</th>
</tr>
<%
List<Product> list = (List<Product>)request.getAttribute("products");
for(int i=0;i<list.size();i++){
Product product = list.get(i);
%>
<tr>
<td><%=product.getId() %></td>
<td><%=product.getPname() %></td>
<td><%=product.getPrice() %></td>
<td><%=product.getPdesc() %></td>
</tr>
<%
}
%>
</table>
</body>
</html>
ProductServlet
p
rotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用service查询商品
ProductService ps = new ProductService();
List<Product> products;
try {
products = ps.getProducts();
//设置属性
request.setAttribute("products", products);
//请求转发
request.getRequestDispatcher("/products.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
request.setAttribute("msg", "服务器异常");
request.getRequestDispatcher("/products.jsp").forward(request, response);
}
}