Javaweb开发了解前端知识九、jsp的内部Servlet

1. jsp的在服务器中的内部结构

2. jsp的三种语法

a) jsp头部的page指令

b) jsp中的三种脚本

i. 声明脚本(类中(非_jspService()方法中)

ii. 表达式脚本(_jspService方法)

iii. 代码脚本(_jspService方法中)

c) jsp中的三种注释

i. html注释

ii. java注释

iii. jsp注释

3. jsp九大内置对象

4. jsp四大域对象

5. jsp中的out输出和response.getWriter输出的区别

6. jsp的常用标签

a) jsp静态包含

b) jsp标签-动态包含

c) jsp标签-转发

7. 静态包含和动态包含的区别



jsp的全称是java server pages.java的服务器页面。动态页面。

jsp主要是为了解决Servlet程序输出html页面,代码过于繁锁事情。

如下是用servlet输入的html页面

public class PrintHtml extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		response.setContentType("text/html; charset=UTF-8");
		//获取字符输出流
		PrintWriter writer = response.getWriter();
		
		writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
		writer.write("<html>\r\n");
		writer.write("	<head>\r\n");
		writer.write("		<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
		writer.write("		<title>Insert title here</title>\r\n");
		writer.write("	</head>\r\n");
		writer.write("	<body>\r\n");
		writer.write("		this is the hello html!\r\n");
		writer.write("	</body>\r\n");
		writer.write("</html>");
	}

}

从上面的代码可以看出其繁琐性,如果HTML页面过于复杂,则servlet就会显得臃肿

jsp技术存的主要目标,就是为了解决Servlet程序输出html过于繁锁。不方便项目的开发和后期维护。

jsp页面和hmlt页面一样。都存放在WebContent目录下。

jsp页面的和html页面的访问一样。

比如:

WebContent目录下有:

a.html 访问的地址是:http://ip:port/工程名/a.html

c.jsp 访问的地址是:http://ip:port/工程名/c.jsp

jsp的本质是一个Servlet程序

当我们第一次访问jsp页面的时候。Tomcat服务器会把jsp页面翻译成为Servlet程序

第一次访问jsp页面的时候(即,每次更改jsp页面该目录下的_jsp.java文件不会自动刷新,需要在浏览器刷新之后,其里面的内容才会发生刷新)。我们会发现,在tomcat服务器的work目录下,会有这些的文件。


我们打开a_jsp.java源文件,我们发现。里面是:


然后根据源码中的继承关系,我们找到了HttpJspBase的实现类(源码),在源码中,不难发现。HttpJspBase其实继承了HttpServlet类,

那么 也就是,我们访问jsp的时候Tomcat服务器帮我们翻译出来的a_jsp类其实也是间接继承了httpServlet类。

那么 说明翻译出来的类,本身也是一个Servlet程序。


那么 我们翻译出来的Servlet程序的源码中,我们发现如下的代码:


又一次证明 jsp页面,是为了解决Servlet程序输出html页面过繁锁这样的事情。

a. jsp 翻译之后 是 a_jsp.java

b. jsp 翻译之后 是 b_jsp.java

2. jsp的三种语法

a) jsp头部的page指令

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

i. language属性 表示jsp翻译之后是指定的java语言内容

ii. contentType属性 设置了jsp页面输出给客户端的数据的类型。


i. pageEncoding属性 设置当前jsp页面的字符集

ii. import属性它可以导入你需要包或类

iii. autoFlush属性自动刷新 out 输出流(缓冲区)。默认值是true(不能改为false

iv. buffer属性它是out输出流的缓冲区,设置了缓冲区的大小。默认是8kb

autoFlush设置为falseout缓冲区满了之后不让执行flush操作,客户端就会发生如下错误,buffer缓冲区溢出。


i. errorPage属性设置当jsp运行时。出错,就会自动跳转去的页面。(为了不给用户一个差的体验)

ii. isErrorPage属性设置当前jsp页面是否是一个错误页面。它会启用Exception异常对象。默认是false

iii. session 属性设置访问jsp页面的时候,是否创建Session会话对象。默认是true

iv. extends 属性给留服务器厂商(一般不会改动)

b) jsp中的三种脚本

i. 声明脚本(类中(非_jspService()方法中)

作用:声明为类中(非_jspService()方法中)的代码

格式脚本的格式是:

<%!   %>

1. 我们可以定义全局变量。

2. 定义static静态代码块

3. 定义方法

4. 定义内部类

<body>
<!-- 		1.我们可以定义全局变量。 -->
		<%!
			private int i = 12;
			private static Map<String,Object> map;
		%>
<!-- 		2.定义static静态代码块 -->
		<%!
			static {
				map = new HashMap<String,Object>();
				map.put("key1", "value1");
				map.put("key2", "value2");
			}
		%>
<!-- 		3.定义方法 -->
		<%!
			public int abc(){
				return 0;
			}
		%>
<!-- 		4.定义内部类 -->
		<%!
			public static class A {
				private int kkk;
			}
		%>
		this is the hello html!<br/>
</body>

务器自动帮我们生成代码在tomca目录下的work工作区间中的对应servletjsp页面中的代码:


ii. 表达式脚本(_jspService方法)

作用: jsp页面中输出数据

表达式脚本格式是:

<%=表达式 %>

表达式脚本可以在jsp页面中输出数据。

达式脚本被翻译之后在_jspService方法中

表达式脚本翻译之后都是out.printl输出

_jspService方法中的对象都可以直接使用。

在表达式脚本中,表达式不能以分号结尾

1. 输出整型

2. 输出浮点型

3. 输出字符串

4. 输出对象

<!-- 		1.输出整型 -->
		<%=124 %><br/>
<!-- 		2.输出浮点型 -->
		<%=12.12 %><br/>
<!-- 		3.输出字符串 -->
		<%="dfsawrqwafsa" %><br/>
<!-- 		4.输出对象 -->
		<%=map %><br/>
<%=12==12?"12等于12":"12不等于12" %><br/>

iii. 代码脚本(_jspService方法中)

作用:

代码脚本它可以在_jspService方法中定义你需要的代码内容。

代码脚本最终会被翻译到_jspService方法中

换句话说。也就是我们能在_jspService方法中写的代码,都可以在代码脚本中编写。

格式:

<% %>

1. 代码脚本----if 语句

2. 代码脚本----for 循环语句

3. 翻译后java文件中_jspService方法内的代码都可以写

<%
			int i = 12 ;
			// if 语句
			if (i == 12) {
				System.out.println("i等于12");
			} else {
				System.out.println("i不等于12");
			}
			
			// for 循环语句
			for (int j = 0; j < 10; j++) {
				System.out.println(j);
			}
			
			String username = request.getParameter("username");
			System.out.println(username);
			// 获取工程名
			System.out.println( application.getContextPath() );
%>

c) jsp中的三种注释

i. html注释

html注释都会被翻译到_jspService方法中,然后以out.write输出到客户端。 

ii. java注释

java注释在翻译之后 ,会被翻译到java源代码中//xxxx 

iii. jsp注释

jsp注释在翻译的时候会被完全忽略掉。

3. jsp九大内置对象


4. jsp四大域对象

application

ServletContext

整个web工程(只要服务器或工程不停。数据都在)

session

HttpSession

览器打开到浏览器关闭    一个会话(打开浏览器请求服务器。中间,只要浏览器不关,会话都在。)

request

HttpServletRequest

请求对象(每次请求,由Tomcat服务器创建)

pageContext

PageContext

在一个jsp页面中,是jsp上下文对象

域对象,就是可以像map一样存取数据的对象

四个域在使用的时候,按从小到大的顺序。

pageContext --->>> request ---->>>> session ---->>>application

测试:

先运行Context1.jsp查看四种结果

Context1.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=UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		<%
			pageContext.setAttribute("key", "pageContext");
			request.setAttribute("key", "request");
			session.setAttribute("key", "session");
			application.setAttribute("key", "application");
		%>
		<h1>Context1.jsp页面</h1>
		pageContext : <%=pageContext.getAttribute("key") %><br/>
		request : <%=request.getAttribute("key") %><br/>
		session : <%=session.getAttribute("key") %><br/>
		application : <%=application.getAttribute("key") %><br/>
		<%
			// 转发中的斜杠 表示到http://ip:port/工程名/		映射到代码的WebContent目录
// 			request.getRequestDispatcher("/context2.jsp").forward(request, response);
			// 重定向的斜杠 表示到http://ip:port/
// 			response.sendRedirect("/Hello/context2.jsp");
		%>
	</body>
</html>

Context2.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=UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		<h1>Context2.jsp页面</h1>
		pageContext : <%=pageContext.getAttribute("key") %><br/>
		request : <%=request.getAttribute("key") %><br/>
		session : <%=session.getAttribute("key") %><br/>
		application : <%=application.getAttribute("key") %><br/>
	</body>
</html>

5. jsp中的out输出和response.getWriter输出的区别

jsp页面中不管是先out输出,还是respose.getWriter()

客户端显示的输出结果都是先输出response.getWriter()out输出

原因如下解析


jsp页面中统一使用out进行输出,不用response。因为在 jsp翻译的源码中都是用out进行输出的javax.servlet.jsp.JspWriter out = null;

out.write 可以输出字符串

out.print 可以输出任意数据。

jsp页面当中,我们可以使用out.print输出

6. jsp的常用标签

a) jsp静态包含

<%--

静态包含的斜杠表示到http://ip:port/工程名/   也就是映射到WebContent目录

 --%>

<%@ include file="/include/footer.jsp" %>

静态包含是把被包含的jsp页面的内容,原封不动的拷贝到静态包含的代码位置,进行输出。

静态包含,只会翻译大的jsp页面。被包含的jsp页面,不会被翻译


b) jsp标签-动态包含

 <%--

 动态包含的斜杠表示到http://ip:port/工程名/   也就是映射到WebContent目录

  --%>

<jsp:include page="/include/footer.jsp"></jsp:include>


动态包含是把全部的jsp页面,都翻译成为servlet程序。然后再通过代码(传递request对象,response对象,out对象给被包含的jsp页面使用)

request.getRequestDispatcher("/context2.jsp").forward(request, response)也是传递request对象和response对象,参数共享
源码_jspService()方法中:JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);

调用被包含的jsp页面的内容。

动态包含,还可以传递参数。

c) jsp标签-转发

<%-- 请求转发,功能跟request.getRequestDispatcher("/context2.jsp").forward(request, response); 一样 --%>

<jsp:forward page="/context2.jsp"></jsp:forward>

7. 静态包含和动态包含的区别

 

静态包含

动态包含

是否生成java文件

不会(只翻译自己)

会(全部)

service方法中的区别

是把被包含的jsp页面的内容原封不动的拷贝到被包含的位置输出

JspRuntimeLibrary.include

是否可以传递参数

不能

可以

编译次数

1

多次

适用范围

静态包含适用于包含那些jsp页面中,只有输出html页面数据的jsp

动态包含适用于那些被包含的jsp页面中包含了大量的java代码,或者运行进来执行时候耗时比较长的jsp页面。

jsp页面在整个javaEE的框架中的定位,它的定位只是用来输出html页面数据。所以一般情况下。我们也就只使用静态包含。静态包含性能会比动态包含经微快。

例题:用jsp输出一个表格,里面有20个学生信息。


表格样式
<style type="text/css">
	table{
		width: 500px;
		border: 1px solid red;
		border-collapse: collapse;
	}
	th , td{
		border: 1px solid red;
	}
</style>

Student对象

public class Student {

	private int id;
	private String name;
	private String phone;
	private String sex;
	private int age;

	public Student(int id, String name, String phone, String sex, int age) {
		super();
		this.id = id;
		this.name = name;
		this.phone = phone;
		this.sex = sex;
		this.age = age;
	}

SearchStudent程序中的代码:

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 省略获取搜索关键字
		// 省略到数据库中去查询
		// 生for循环生成 数据库查询的结果
		List<Student> stus = new ArrayList<Student>();
		for (int i = 0; i < 10; i++) {
			stus.add(new Student(i,"name-" + i,"phone-" + i,(i%2==1?"男":"女"), 18+i));
		}
		// 需要保存到request域对象中
		request.setAttribute("stus", stus);
		// 转发到jsp页面
		request.getRequestDispatcher("/showStudent.jsp").forward(request, response);
	}

jsp页面中的代码:

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="com.atguigu.pojo.Student"%>
<%@ 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>Insert title here</title>
		<style type="text/css">
			table{
				width: 500px;
				border: 1px solid red;
				border-collapse: collapse;
			}
			th , td{
				border: 1px solid red;
			}
		</style>
	</head>
	<body>
		<%
			List<Student> stus = (List<Student>) request.getAttribute("stus");
		%>
		<table>
			<tr>
				<th>编号</th>
				<th>姓名</th>
				<th>电话</th>
				<th>性别</th>
				<th>年龄</th>
				<th>操作</th>
			</tr>
		<% for (int i = 0; i < stus.size(); i++) { %>
			<% Student s = stus.get(i); %>
			<tr>
				<td><%=s.getId() %></td>
				<td><%=s.getName() %></td>
				<td><%=s.getPhone() %></td>
				<td><%=s.getSex() %></td>
				<td><%=s.getAge() %></td>
				<td>删除,修改</td>
			</tr>
		<% } %>
		</table>
	</body>
</html>


Javaweb开发了解前端知识八、Servlet(二)


猜你喜欢

转载自blog.csdn.net/mxcsdn/article/details/80467694