web学习五——JSP

本文详细介绍了JSP的由来、本质、工作原理以及JSP的三种语法、内置对象、JSTL标签库、自定义标签库、EL表达式等内容,揭示了JSP如何将HTML和Java代码结合,以及JSP与Servlet的关系。同时探讨了JSP的开发模式,包括JSP+JavaBean和Servlet+JSP+JavaBean(MVC)模式,强调了在复杂web应用中的使用场景和优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

web应用中path的写法小结

  • 每次写路径,给谁用?上来先写个/
  • 浏览器-----/表示当前的主机名
  • web应用—/表示当前web应用的根目录
  • 1.转发
  • 2.重定向
  • 3.读取web应用下资源文件
  • 4.表单提交数据
  • 5.超链接a标签
  • 6.img标签,src
  • 7.使用类加载器获得文件的路径
  • 8.url重写http://localhost:8080/day11/servlet;jsessionid=KKVSLJFHSIFISH
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
//		 * 1.转发
		request.getRequestDispatcher("/login.jsp").forward(request, response);
//		 * 2.重定向
		response.sendRedirect("/day11/login.jsp");
//		 * 3.读取web应用下资源文件
		getServletContext().getRealPath("/1.txt");
//		 * 4.表单提交数据
//		<form action="/day11/login.jsp"></form>
//		 * 5.超链接<a>标签
//		<a href="/day11/login.jsp"></a>
//		 * 6.<img>标签,src
//		<img src="/day11/checkimage">		
//		 * 7.url重写    http://localhost:8080/day11/servlet;jsessionid=KKVSLJFHSIFISH	
		response.encodeUrl("/day11/login");
//		 * 8.使用类加载器获得文件的路径
		PathSummary.class.getClassLoader().getResource("1.txt");
		
		InputStream in = PathSummary.class.getClassLoader().getResourceAsStream("2.jpg");
		
		InputStream in2 = getServletContext().getResourceAsStream("WEB-INF/classes/2.jpg");
		//少用;
//		PathSummary.class.getResource("/1.txt");
		}

7 JSP

7.1 jsp的由来

Servlet对页面的美化是不擅长的

  • SUN公司为了解决这个问题,就参考了asp的语法,弄出了jsp的技术规范
  • asp、jsp、php
  • jsp:html代码(html、css、js)和java代码

1.What is JSP
JSP( JavaServer Pages )是由Sun 公司倡导、许多别的公司参与一起建立的一种新动态网页
技术标准,类似其他技术标准,如ASP、PHP 或是ColdFusion,等等。
在传统的网页HTML 文件( .htm,.html )中加入Java程序片段( Scriptlet )和JSP标签,构成了JSP 网页(*.jsp)。Servlet/JSP Container 收到客户端发出的请求时,首先执行其中的程序片段,然后将执行结果以HTML格式响应给客户端。其中程序片段可以是:操作数据库、重新定向网页以及发送 E-Mail 等等,这些都是建立动态网站所需要的功能。所有程序操作都在服务器端执行,网络上传送给客户端的仅是得到的结果,与客户端的浏览器无关,因此,JSP 称为Server-SideLanguage。

2.Microsoft 和 Sun 都提供它们各自品牌的服务器页面。Sun提供JavaServer Pages (JSP)而 Microsoft 提供 Active Server Pages(ASP)。JSP 和 ASP 都设计成使开发者能够从后端系统产生动态页面。
虽然表面看起来相似,ASP 和JSP仍有一些不同之处:
JSP 是平台独立性的,一次编写,随处运行;
开发者通过Java Community Process(JCP)指引方向;
JSP 开发者可以通过定制标签扩展JSP标签库;
JavaBeans 和 Enterprise JavaBeans (EJB) 可以和JSP一起使用,增强可重用性和减小维护。
JSP 可以存取其他一些Java 库,包括Java 数据库连接(JDBC),Java Mail,Java Message
Service(JMS),以及JNDI。
JSP 编译成二进制类文件,不需要在每次请求时进行解释;
JSP 有广泛的支持,包括工具,容器和服务器。

7.2 JSP介绍

Jsp 本质上就是 serlvet , jsp 在 第一次被访问的时候, 会被 编译生成一个serlvet类, 然后 再编译生成 一个.class文件, 然后由 jvm 加载运行。
问题1.为什么是jsp 本质上就是serlvet:
查看 work 目录下 , 找到了 jsp 对应 的 被翻译成 serlvet类, 打开后发现
这里写图片描述
这里写图片描述
所以 jsp 本质上就是 servlet …
结论 : 访问JSP实际上就是访问 serlvet . …
Jsp 比 servlet 要来的更加方便. (jsp 访问 不需要 配置 对外访问路径, 直接访问就好 … )

Jsp的翻译过程详解:
这里写图片描述
JSP 的执行过程:
(1) 客户端发出Request (请求);
(2) JSP Container 将JSP 翻译成Servlet 的源代码;
(3) 将产生的Servlet 的源代码经过编译后,加载到内存执行;
(4) 把结果Response (响应)发送至客户端。
JSP和Servlet的执行效率相差不大,只是第一次执行JSP页面时需要进行编译。
一般人都会以为JSP 的执行性能会和Servlet 相差很多,其实执行性能上的差别只在第一次的执行。因为JSP 在执行第一次后,会被编译成Servlet 的类文件,即为XXX.class,当再重复调用执行时,就直接执行第一次所产生的Servlet,而不用再重新把JSP编译成Servlet。因此,除了第一次的编译会花较久的时间之外,之后JSP 和Servlet 的执行速度就几乎相同了。
在执行JSP 网页时,通常可分为两个时期:转译时期(Translation Time)和请求时期(Request Time) 。

  1. JSP文件先要被服务器翻译成Java文件(Servlet),在tomcat中翻译后的Java文件在tomcat下的 work/Catalina /localhost 中相应名字的应用目录里。
  2. 编译成Java(Servlet)文件
  3. 运行.class文件

由于jsp\ 被访问时 存在以上若干步骤, 所以 jsp在第一次访问的时候 会比较慢, 但是 后续的请求 , 就是 拿 内存中的serlvet实例对象来响应客户端的请求了, 所以 就会很快了.
以后如果 要去找jsp 对应的被翻译的servlet, 那么需要 到 tomcat服务器下的 work 目录下去找.

7.3 JSP的三种语法

<!-- jsp的声明
使用声明的语法,所声明的变量、方法、构造函数都会被翻译到对应的Servlet的成员变量和成员函数中去 -->
<%!int m=10;%>

<!-- jsp的脚本表达式
由于输出数据使用的是脚本表达式,最终使用的是out对象 输出的,在jsp中out是一个内置的对象,所以之后可以使用out输出数据-->
<%=  10 %>

<!-- jsp的java代码
通过这种形式可以写任何形式的Java代码-->
<%int p=100;%>
<%for(int i=0;i<4;i++){
	out.print(i);
} %>

<%--jsp注释,转化阶段消失,只有开发人员能够看到 --%>
<%//java代码的注释,编译阶段消失
/**文档注释*/
/*
   多行注释
*/
%>
<!-- html代码注释 ,不会消失,在页面中也能看到-->
执行顺序先后jsp>java>html

JSP指令元素
格式:<%@ directive [ attribute =“value” ] * %>
分类:
page指令标记(用来定义JSP文件的全局属性)
这里写图片描述
这里写图片描述
include指令标(在JSP页面中静态包含一个文件,同时由JSP解析包含的文件内容,包含的是目标文件的源码;包含过来,一起翻译)在JSP页面中,只有import可以出现多次,其它属性都只能出现一次。
格式:<%@ include file=“filename” %>

taglib指令标记 (在JSP页面中导入标签库,常用标签库为JSTL,
常用属性:
uri 标签文件的URI地址
prefix 标签组的命名空间前缀)

7.4 JSP内置对象

这里写图片描述
内置对象的类型
这里写图片描述

Page:代表了正在运行的由JSP文件产生的类对象,指向当前JSP程序本身的对象this,其实是java.lang.Object类的实例对象.

pageContext:“页面上下文”对象,代表的是当前页面运行的一些属性.提供了对JSP页面所有的对象及命名空间的访问.
通过pageContext获得其他对象:
这里写图片描述
out对象
这里写图片描述
这里写图片描述
exception对象
用来处理JSP文件在执行时所有发生的错误和异常,可以和page指令一起使用,通过指定某一个页面为错误处理页面,对错误进行处理<%@ page isErrorPage=”true “%>的页面内使用
JSP常用标签
这里写图片描述
两种include用法的区别:
这里写图片描述

7.5 JSTL 标签库

核心标签库 (core) — c(day12/jstl)
<c:out> 标签用于输出一段文本内容到pageContext对象当前保存的“out”对象中。
<c:set>标签用于把某一个对象存在指定的域范围内,或者设置Web域中的java.util.Map类型的属性对象或JavaBean类型的属性对象的属性。
<c:remove>标签用于删除各种Web域中的属性。
<c:catch>标签用于捕获嵌套在标签体中的内容抛出的异常,其语法格式如下:<c:catch [var="varName"]>nested actions</c:catch>
<c:if test=“”>标签可以构造简单的“if-then”结构的条件表达式
<c:choose>标签用于指定多个条件选择的组合边界,它必须与<c:when><c:otherwise>标签一起使用。使用<c:choose><c:when><c:otherwise>三个标签,可以构造类似 “if-else if-else” 的复杂条件判断结构。
<c:forEach>标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。
<c:forTokens> 用来浏览一字符串中所有的成员,其成员是由定义符号所分隔的
<c:param>标签可以嵌套在<c:import><c:url><c:redirect>标签内,为这些标签所使用的URL地址附加参数。
<c:url>标签用于在JSP页面中构造一个URL地址,其主要目的是实现URL重写。URL重写就是将会话标识号以参数形式附加在URL地址后面 。
<c:redirect>标签用于实现请求重定向

国际化标签 fmt
数据库标签 sql --Servlet
XML标签 xml
JSTL函数(EL函数) el

7.6 自定义标签库

主要用于移除Jsp页面中的java代码
Tag接口的执行流程

7.7 EL 表达式

EL主要作用:
**1.**获取数据:某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组(day12/el)
**2.**执行运算:在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}
**3.**获取web开发常用对象:EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
pageContext 对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。) ------->可以用来获得8个隐式对象
pageScope 代表page域中用于保存属性的Map对象
requestScope 代表request域中用于保存属性的Map对象
sessionScope 代表session域中用于保存属性的Map对象
applicationScope 代表application域中用于保存属性的Map对象
param 表示一个保存了所有请求参数的Map对象
paramValues表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
header 表示一个保存了所有http请求头字段的Map对象
headerValues同上,返回string[]数组。注意:如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
cookie 表示一个保存了所有cookie的Map对象 ${cookie.name.value}
initParam 表示一个保存了所有web应用初始化参数的map对象

**4.**调用Java方法:EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
使用el表达式调用Java类步骤(day12/el/7.jsp):
**1.**建一个java类,Java类中被调用的方法一定是静态的
例如:com.lln.operation.Operation 注意方法是静态的

	
	public static String encodeContent(String content) {
		try {
			
			//URLEncoder可以对字符进行URL编码
			//URLDecoder可以对%形式的字符进行解码
			return URLEncoder.encode(content, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

	public static String decodeContent(String content) {
		try {
			
			//URLEncoder可以对字符进行URL编码
			//URLDecoder可以对%形式的字符进行解码
			return URLDecoder.decode(content, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}

} 

**2.**通过向导的方式去建一个tld文件,这个tld文件一定要放在WEB-INF目录下,一定不要放在lib或classes目录下注意:这个文件有缺陷。要把schemaLocation的值改为:
xsi:schemaLocation=“http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd
myel.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>llnel</short-name>
<uri>http://www.lln.com/llnel</uri>
<function>
   <name>contains</name>
   <function-class>com.lln.operation.Operation</function-class>
   <!-- public static String encodeContent(String content) -->
   <function-signature>java.lang.String encodeContent(java.lang.String)</function-signature>
 </function>
 <function>
   <name>decodes</name>
   <function-class>com.lln.operation.Operation</function-class>
   <!-- public static String encodeContent(String content) -->
   <function-signature>java.lang.String decodeContent(java.lang.String)</function-signature>
 </function>
</taglib>```
**3.**在这个文件中添加:
//el函数对应的名称 contains // el函数对应的完整的包名 com.lln.operation.Operation // el函数对应的java类的方法签名 java.lang.String encodeContent(java.lang.String) ``` **4.**使用taglib指令导入标签 <%@ taglib uri="http://www.lln.com/llnel" prefix="llnel" %> **5.**使用: ${llnel:contains("玲玲")}

主要用于取出 域对象中的数据
语法: ${name}取出 存在 域对象中 调用的 setAttribute(name, obj) 的 值

<% request.setAttribute("name","张三"); %>
<%String value=(String)request.getAttribute("name"); %>
<%=value %>
<%out.println(value); %>
<%=request.getAttribute("name") %>
${name }

EL函数库—JSTL中的常用EL函数

fn:toLowerCase函数将一个字符串中包含的所有字符转换为小写形式,并返回转换后的字符串
fn:toUpperCase函数将一个字符串中包含的所有字符转换为大写形式,并返回转换后的字符串
fn:trim函数删除一个字符串的首尾的空格,并返回删除空格后的结果字符串
fn:length函数返回一个集合或数组大小,或返回一个字符串中包含的字符的个数
fn:split函数以指定字符串作为分隔符,将一个字符串分割成字符串数组并返回这个字符串数组
fn:join函数以一个字符串作为分隔符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串
fn:indexOf函数返回指定字符串在一个字符串中第一次出现的索引值
fn:contains函数检测一个字符串中是否包含指定的字符串
fn:startsWith函数用于检测一个字符串是否是以指定字符串开始的
fn:replace函数将一个字符串中包含的指定子字符串替换为其它的指定字符串,并返回替换后的结果字符串
fn:substring函数用于截取一个字符串的子字符串并返回截取到的子字符串
fn:substringAfter函数用于截取并返回一个字符串中的指定子字符串第一次出现之后的子字符串

7.8 JSP开发模式

JSP发展模式
这里写图片描述
一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式。
1.JSP+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据。
这里写图片描述
2.Servlet+JSP+JavaBean(MVC)模式适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP、JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。 (高内聚, 低耦合)
这里写图片描述
MVC设计模式
把应用程序分成三个核心模块:模型、视图、控制器
这里写图片描述
JavaBean特点
1.这个Java类必须具有一个无参的构造函数
2.属性必须私有化。
3.私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。
JSP中使用JavaBean
<jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
<jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
<jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
访问JavaBean属性的两种方式:
1.直接调用bean的setXXX或getXXX方法。
2.通过内省技术访问(java.beans包提供了内省的API)

/*
	 * 获取JavaBean的属性
	 * BeanInfo beanInfo=Introspector.getBeanInfo(Person.class);与
	 * BeanInfo beanInfo=Introspector.getBeanInfo(Person.class,Object.class);
	 */	
	@Test
	public void test1() throws Exception {
		//sun公司提供了一套专门的api用来操作JavaBean的属性
		//内省---Introspector
		
		BeanInfo beanInfo=Introspector.getBeanInfo(Person.class);
		
		PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
		System.out.println(pds.length);
		for(PropertyDescriptor pd:pds) {
			System.out.println(pd.getName());
		}
	}
	
	@Test
	public void test2() throws Exception {
		//sun公司提供了一套专门的api用来操作JavaBean的属性
		//内省---Introspector
		
		BeanInfo beanInfo=Introspector.getBeanInfo(Person.class,Object.class);
		
		PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
		System.out.println(pds.length);
		for(PropertyDescriptor pd:pds) {
			System.out.println(pd.getName());
		}
	}

BeanUtils的框架,专门用于操作Bean,完成数据的封装
1.apache专门提供了一个BeanUtils的框架,专门用于操作Bean,完成数据的封装
2.使用beanUtils核心类,beanUtils封装数据时有个要求,(目标JavaBean的字段要与提交过来的参数名称保持一致,否则不能完成)
User user=new User();
BeanUtils.populate(user, request.getParameterMap());
读取xml文件—dom4j
1.首先需要导入dom4j的jar包

		Document document=XMLUtils.getDocument();
		//遍历document下的user元素,拿到username和email,看用户名和密码是否已经被占用
		//如果在那,则返回相应的值,提示
		
		//获得根元素
		Element rootElement=document.getRootElement();
		//空指针异常,肯定是你调用了某个对象的方法;这个对象为空
		//找到那个目标行,看那行里面有没有.   没有.的话,肯定就是.之前的那个对象为空
		List<Element> userelements=rootElement.elements("user");
		
		for(Element element:userelements)
		{
			if(element.elementText("username").equals(user.getUsername())) {
				//说明用户名已存在
				return USERNAME_EXIST;
			}
			
			if(element.elementText("email").equals(user.getEmail())) {
				//说明邮箱已存在
				return EMAIL_EXIST;
			}
			
		}
		
		//如果走到这里,说明用户名和邮箱都没有被占用,完成注册,把用户信息保存到xml文件中去
		
		Element newAddUserElement=rootElement.addElement("user");
		newAddUserElement.addElement("username").setText(user.getUsername());
		newAddUserElement.addElement("password").setText(user.getPassword());
		newAddUserElement.addElement("nickname").setText(user.getNickname());
		newAddUserElement.addElement("eamil").setText(user.getEmail());
		
		XMLUtils.writeBack2Xml(document);
/*
 * 如果放到WEB-INF目录下,你要获得路径需要使用的是ServletContext,而当前的类是一个普通的Java类,
 * 不能直接拿到对ServletContext对象的引用
 * 2.推荐放到src目录下,会被发布到classes目录下,可以使用类加载器去读取
 */
				
public class XMLUtils {
		private static String filepath=XMLUtils.class.getClassLoader().getResource("user.xml").getFile();
	
     //返回代表xml文件的document对象
	public static Document getDocument() {
		SAXReader reader=new SAXReader();
		try {
			System.out.println(filepath);
			return reader.read(filepath);
		} catch (DocumentException e) {
			e.printStackTrace();
			return null;
		}
		
	}
	//将内存中的document对象写回到xml文件中去
	public static void writeBack2Xml(Document document) {						
			try {
				OutputFormat format=OutputFormat.createPrettyPrint();
				format.setEncoding("UTF-8");
				XMLWriter writer=new XMLWriter(new FileOutputStream(filepath),format);
				writer.write(document);
				writer.close();
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			} 
	}

}

案例:模式二实现用户注册登录分析(day13)
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值