一.Servletphp
思考html
1 浏览器能够直接打开JAVA/class文件吗? 不能够java
2浏览器能够打开HTML、JS 文件吗? 能够程序员
3 JAVA程序能够生成HTML文件吗?能够的,用IO流。web
4 浏览器解析的时候是须要HTTP协议的,JAVA普通类有没有HTTP协议呢? 普通类没有.sql
JAVA-(class)浏览器如何访问呢?编程
浏览器---HTML浏览器
A JAVA经过IO流生成HTML--->浏览器 缓存
B JAVA 须要加入HTTP协议tomcat
解决上面2个问题能够经过 Servlet
C 如何经过浏览器访问Servlet
它须要用到一个文件web.xml (webroot-->web-inf--web.xml)
Sevlet它是什么?
Servlet是一个容器(引擎),它包含协议和支持功能的jar包,它是一个总体。
在使用的时候咱们不用去关内心面的核心程序,咱们只关心业务程序。
业务程序 程序员所写支持协议的类,有一种特殊的叫法 Serlvet类。
1.三要素是什么?
入口(login.html) 处理(LoginServlet.java) 出口 (success.jsp)
2.如何访问servlet
http://IP:port/project/urlpattern
urlpattern ---->web.xml中找
3 request 和 response的区别?
Request请求 Broswer---->Tomcat login.html--->LoginSevlet.java
Response返回 Tomcat---->Broswer
4 doGet 和 doPost的区别?
doGet <a href=url> 超连接用的默认方式 get 不解中文决乱么
<form action=url method=get >
明文传递方式 浏览器中能够看到传递的信息
不安全,而且数据量大的时候会缺损数据
doPost <form action=url method=post > 解决中文乱码
密文传递方式 浏览器看不到传递的信息
安全,而且数据量大的时候不会缺损数据
5如何解决乱码问题?
Request请求有乱码
request.setCharacterEncoding("UTF-8");
Reponse返回有乱
response.setCharacterEncoding("UTF-8");
6 如何取得请求中的值 ?
String value=request.getParameter(“控件名”); 单个值
String [] values=request.getParmeterValues(“控件名”); 同名多个值
7 常见的错误:404 、500?
404 路径错误---解决思路 跟踪路径
500 代码错误---解决思路 jsp/servlet中代码错误
获取不到值null 在console里面去找到错误的位置。
8 servlet中获得流的方法?
字符流 response.getWriter( )----->PrintWriter
字节流 response.getOutputStream()-->OutputStream
9 如何跳转到出口?
//跳转而且能够传递数据
request.getRequestDispatcher("success.jsp").forward(request, response);
//从新定向 跳转不传递数据
response.sendRedirect("success.html");
10如何将数据传递到出口?
//保存数据
request.setAttribute("name", username);
request.setAttribute("password", pwd);
//获取数据
用户名是:${ name} ,密码: ${password}。
11 Servlet的生命周期
Servlet的生命周期是由tomcat服务器来控制的。
1 构造方法:
建立servlet对象的时候调用。默认状况下,第一访问servlet就会建立servlet对象只建立一次。说明servlet对象在tomcat中是单实例的。
2初始化 init方法
当建立完servlet对象的时候会调用init()方法,只调用一次。
3 调用服务 service 方法 其中就包含doGet doPost等方法
每次发送请求的时候调用。能够调用n次。
4 销毁 destory 方法
销毁servlet对象的时候调用,中止服务器或者从新部署的web项目的时候销毁servlet就会调用destory方法
12 Servlet时序图
13 servlet自动加载
在web.xml中加入
<load-on-startup> 1</load-on-startup>
里面的数字越小加载级别越高
当tomcat启动的时候,就去运行web.xml解析里面的内容,当发现有自动加载的数据时候,就会运行加载。
<servlet> <servlet-name>sl</servlet-name> <servlet-class>com.bw.servlet.LoginServlet</servlet-class> <load-on-startup>3</load-on-startup> </servlet> |
14 ServletConfig 对象
主要是加载servlet的初始化参数,在web应用中能够存在多个ServletConfig对象
<servlet> <servlet-name>sl</servlet-name> <servlet-class>com.bw.servlet.LoginServlet</servlet-class> <init-param> <param-name>username</param-name> <param-value>godyang</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>123456</param-value> </init-param> </servlet> |
15 ServletContext对象
上下文对象,表示当前的web应用(项目)环境。一个web应用只有一个ServletContext对象
上下文参数配置 它是全局的 全部的servlet均可以访问
<context-param> <param-name>ecode</param-name> <param-value>UTF-8</param-value> </context-param> |
// 获取上下文对象 ServletContext sc = this.getServletContext(); String contextParamValue = sc.getInitParameter("ecode"); System.out.println("contextParamValue=" + contextParamValue); |
//项目路径 String path=sc.getContextPath(); System.out.println("path="+path); //文件发布后(tomcat/webapps)的真实路径 String realPath=sc.getRealPath("counter.txt"); System.out.println("realPath="+realPath ); //获取文件流 InputStream is=sc.getResourceAsStream("C:\\Tomcat\\webapps\\webThree\\WEB-INF\\classes\\counter.txt");
|
二.JSP技术
Jsp技术是用来开发java web的页面显示的,全部MVC模型里面的视图层,因此视图层的开发
jsp不是编程语言,java server pages的缩写
Jsp其实也是继承Servlet的,属于在服务器上的开发。Servlet是用于java语言的动态资源开发的技术,而Jsp是把java和html结合,在html中能够写java语言,主要用在页面的显示开发上。
1.1.Jsp的特色
1.Jsp的运行必须交给tomcat服务器。tomcat的work目录就是服务器用来存放jsp运行时的临时文件的
2.Jsp页面便可直接写html代码,也能够直接写java代码
2.Jsp的执行过程
问题1:访问http://localhost:8080/hello/index.jsp 如何显示效果?
1.访问到index.jsp页面,tomcat扫描到jsp文件,在tomcat/work目录下把jsp文件翻译成java源文件
index.jsp-->index_jsp.java(翻译)
2.tomcat服务器把java源文件编译成class字节码文件(编译)
index_jsp.java-->index_jsp.class
3.tomcat服务器构造index_jsp类对象
4.tomcat服务器调用index_jsp类里面的方法,返回内容显示到浏览器
若是是第一次访问当前jsp文件时,执行步骤是:1-->2-->3-->4
第N次访问jsp时,执行步骤是:4,再也不执行其余步骤
注意:jsp文件被修改或者jsp的临时文件被删除了,要从新走翻译 1 和编译 2 的过程
问题2:既然jsp是servlet,那么jsp的生命周期和servlet的生命周期是否是同样的?
当jsp文件被翻译成java的源码时,能够在翻译出来的源码文件里看到当前访问的jsp文件继承HttpJspBase类,再经过查询JDK,能够发现HttpJspBase又是继承于HttpServlet的。因此,能够获得结论,jsp既是一个servlet的程序,而servlet的技术能够用在jsp程序中,可是并非全部的servlet技术所有适用于jsp程序
Servlet的生命周期:
1.构造方法(第一次访问执行)默认状况第一次使用的时候 经过单例模式建立一个servlet对象
2.init方法初始化(第一次访问执行)当构造了以后就会调用初始化方法 只调用一次
3.service方法(每n次访问都会执行)每次发出请求的时候调用能够调用n次
4.destory方法(退出时执行)关闭服务软件从新部署的时候销毁 servlet对象
Jsp的生命周期:
1.翻译:Jsp-->java文件
2.编译:java-->class文件(servlet程序)
3.构造方法(第一次访问时执行)
4.init方法(第一次访问):_JspInit()
5.service方法:_JspService()
6.destory方法:_jspDestory()
问题3:JSP和Servlet做用有什么区别?
1.Servlet做用: 用java语言开发动态资源( java 流 )的技术.
2.JSP 做用:用java语言开发动态(java 流)+静态资源(html)的技术
3.Jsp语法
3.1.Jsp模板
JSP 页面中会自动添加HTML代码内容,该JSP是模板
这些模板定义了网页的基本骨架,也就是说定义了页面的结构和外观
3.2.Jsp表达式
JSP的表达式做用是向浏览器输出变量的值或表达式计算的结果
语法:<%=变量或表达式 %>
例如<% String name="Eric";%>
<%=name%>
注意:
1.表达式的原理即便翻译成out.print("变量“);经过该方法向浏览器写出内容。
2.表达式后面不须要带分好结束
3.3.Jsp的脚本
脚本是指在JSP页面编写多行java代码的,能够执行java代码
语法:<%多行java代码; %>
如:
<%
Date date = new Date();
SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
String now = sdFormat.format(date);
out.println(now);
%>
注意
1.原理是把脚本中的java代码原封不动的拷贝到jspService方法中执行
2.jsp脚本中写的java是须要加分好的,语法跟java语法是同样的
3.多个脚本片断中的代码能够相互访问
4.单个脚本片断中的java语句能够是不完整的,可是,多个脚本片断组合后的结必须是完整的java语句
3.4.Jsp的声明
JSP的声明是用来声明变量或者方法的,若是在index.jsp页面内声明一个变量或者方法,则该变量或者方法是index_jsp类的成员变量,成员方法,便是全局变量。这个其实就是在类中写好方法,而后能够在jsp_service方法中调用其余方法。
jsp经过脚本也能够定义一个变量,可是这个变量是保存在index_jsp类下的jspService方法下的一个变量,因为是保存在方法下面,全部脚本里是不能够定义一个方法的,只能经过声明来定义方法。
注意以上二者的区别,一个是保存在类下面,称为成员变量或者成员方法,另外一个则是保存在方法中,称之为局部变量
语法:<%! 变量或方法%>
做用:声明JSP的变量和方法
注意:
1.变量翻译成成员变量,方法翻译成成员方法
3.5.Jsp的注释
jsp的注释格式:
jsp的注释:<%!--jsp注释 --%>
html的注释:
注意:
1.html的注释会被翻译和执行,不管在jsp的页面翻译以后的源码仍是在浏览器上查看网站的源码,都是能够查看到的。可是jsp的注释是不会被翻译和执行的,在翻译以后源码里是不能找到的,从浏览器查看源码也是查看不到的
4.Jsp的三大指令
JSP指令是为JSP引擎而设计的,他们并不产生任何可见的输出,只是告诉引擎如何处理jsp页面中的其他部分。jsp定义的有三大指令,分别是:include,page,tagllb
4.1.Include指令
Include指令的做用是当前页面包含其余页面,主要是导入其余jsp文件
语法:<%@include file="common/header.jsp%>
注意:
1.原理是把被包含的页面(header.jsp)的内容翻译到包含页面(index.jsp)中,合并并翻译成一个java源文件,再编译运行!!,这种包含就加叫静态包含(源码包含)
2.若是使用静态包含,被包含页面中不须要出现全局的html标签了,(如html,body,head)
4.2.page指令
page指令的做用是告诉tomcat服务器如何翻译jsp文件
语法:<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page
language="java" --使用的语言
import="java.util.*" --须要导入的类
pageEncoding="UTF-8" --jsp编码方式
contentType="text/html; charset=UTF-8" --tomcat将html流发送给浏览器的文件类型和编码方式
errorPage="error.jsp" --当前jsp页面解析错误的时候就会跳转到error.jsp去
isErrorPage="false" --当前页面是否是错误导向页面
%>
language="java"--告诉服务器只用什么动态语言来翻译jsp文件
import="java.util.*" --告诉服务器java文件使用什么包,导入多个包时,用逗号隔开
pageEncoding="utf-8" --告诉服务器使用什么编码把jsp翻译成java文件
contentType="text/html; charset=utf-8" --服务器发送浏览器的数据类型和内容编码,在开发工具中,只须要设置pageEncoding便可解决中文乱码的问题
errorPage="error.jsp" --若是当前页面出现错误信息,则自动调用此处指定的错误页面
isErrorPage="false" --意思是当前页面为错误页面,默认为false,当设置为true时就认为是一个错误处理页面,就能够在页面中使用<%=exception.getMessage()%>方法来获取错误异常信息,使其在页面上能够显示
全局配置错误处理页面
在web.xml中配置以下:
<!--全局错误处理页面配置-->
<error-page>
<error-code>500</error-code>
<location>common/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>common/404.html</location>
</error-page>
配置以后,不用在jsp页面中特别指明,会自动跳转的
session="true" --是否开启Session功能,false时不能使用Session内置对象,ture时可使用。默认为true
buffer="8kb" --页面的缓存区大小。
isELIgnored="false" --是否忽略EL表达式。
page==this 对象 通常用在编译指令中 <%@ page %>
4.3.tagllb指令
语法<%taglib %>
做用:标签指令 用来解析标签效果
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
5.JSP的内置对象
5.1.什么是内置的对象
service开发中会常常用到一些经常使用的类好比:HttpSession, ServletConfig, ServletContext, HttpServletRequet,用的时候,咱们会直接建立就能够了,可是在jsp中这会常用到这些类。为了开发的方便,sun公司在设计jsp的时候,在jsp页面加载完毕之后就自动帮开发者建立好了这些对象,而开发者只须要直接使用这些对象就能够了,那么这些已经建立好的对象有一个统一的名字叫作内置对象,内置对象一共有九个
例如:
在Service中要使用Session,须要先HttpSession session = request.getSession(true); 来建立一个Session对象,而后在使用对象的方法
可是在JSP中,能够直接使用Session的方法,如session.getId();
九大内置对象
jsp |
servlet |
|
对象名 |
类型 |
使用范围 |
request |
HttpServletRequest |
请求 浏览器--->服务器 |
response |
HttpServletResponse |
返回 服务器--->浏览器 |
config |
ServletConfig |
用来获取web.xml中的信息 |
application |
ServletContext |
整个项目中的全局信息 |
exception |
Thrawable |
捕获异常 try/catch throws |
page |
this |
当前对象,当前页面对象 |
out |
JspWriter---->PrintWriter |
当前页面输出流 |
pageContext |
PageContext |
当前页面的上下文,整个页面 |
Session |
HttpSession |
会话 浏览器和服务器通信 |
即:
1.对象名(request)-->类型HttpServletRequest :HTTP请求的时候使用到
2.对象名(response)-->类型HttpServletResponse :HTTP响应的时候用到
3.对象名(config)-->类型ServletConfig :获取属于本身的参数
4.对象名(application)-->类型ServletContext :获取全局参数
5.对象名(exception)-->类型Throwable :异常
6.对象名(page)-->类型 Object(this) :本jsp对象
7.对象名(out)-->类型JspWriter :打印到浏览器
8.对象名(pageContext)-->类型PageContext
9.对象名(session)-->类型HttpServletSession :会话管理使用
5.2.Out对象
out 对象 JspWriter 带缓冲的PrinterWriter 就是输出流 , 使用范围是当前页面,超出了当前页无效
1.PrintWriter: 直接向浏览器输出内容
用write直接向浏览器(输出)写出内容
2.JspWrite: 向Jsp 缓冲区写内容
用write向jsp的缓冲区写内容,当缓冲区知足一下条件的时候,把内容一块儿写到浏览器上,性能高于PrintWriter
当知足一下条件之一,JSP缓冲区内容写出到浏览器:
(1) 缓冲区满了
(2)刷新缓存去:out.flush();
(3)关闭缓冲区:buffer="0kb";
(4)执行完毕JSP页面
‘out.print()
‘out.println();
5.3.pageContext对象
前面已经有了8个内置对象,这些对象都是在jsp_service方法中被建立的,而后直接使用,可是因为是在方法中被建立,属于局部变量,因此很难在其余方法被调用,全部,使用了PageContext把这八个内置对象封装起来,这样传参的时候只须要传一个就能够了,而后经过这个PageContext来调用
除了调用其余八个内置对象意外,PageContext自己也是一个域对象,能够传递参数,准确的说PageContext是jsp的上下文对象,只能够在当前jsp文件内传参
分别介绍PageContext的两个方法:
1.能够获取其余八个内置对象
源码分析:
public class 01_hello_jsp {
public void _jspService(request,response){
建立内置对象
HttpSession session =....;
ServletConfig config = ....;
把8个常用的内置对象封装到PageContext对象中
PageContext pageContext = 封装;
调用method1方法
method1(pageContext);
}
public void method1(PageContext pageContext){
但愿使用内置对象
从PageContext对象中获取其余8个内置对象
JspWriter out =pageContext.getOut();
HttpServletRequest rquest = pageContext.getRequest();
........
}
}
注意:调用的时候,使用getout,getrequest等方法来调用
使用场景:在自定义标签的时候,PageContext对象对象频繁使用到
2.PageContext自己就是一个域对象
常用的域对象有4个,分别是
ServletContext context域
HttpServletRequest request对象
HttpSession session域
PageContex page域
PageContext域的做用是保存数据和获取数据,用于共享数据
经常使用方法以下:
保存数据
1.默认状况下,保存到page域
pageContext.setAttribute("name");
2.能够向四个域对象保存数据
pageContext.setAttribute("name",域范围常量)
获取数据
1.默认状况下,从page域获取
pageContext.getAttribute("name")
2.能够从四个域中获取数据
pageContext.getAttribute("name",域范围常量)
3.自动在四个域中搜索数据
pageContext.findAttribute("name");
顺序: page域 -> request域 -> session域- > context域(application域)
5.4.page对象 page==this 对象 通常用在编译指令中 <%@ page %>
5.5.request对象
request 请求 浏览器到服务器
当前请求存属性值 |
request.setAttribute("name","godyang"); |
当前请求取值 |
request.getAttribute("name") |
请求传递参数 |
<a href="b.jsp?name=shunshun"> b.jsp</a> 或者 <form action="b.jsp" method=post > <input type=text name="name" value="shunshun" /> </form>
|
取得请求参数的值 |
request.getParameter(参数名); request.getParameterValues(参数名) |
5.6.reponse 对象
reponse 返回 服务器返回到浏览器
获取返回流 |
PrintWriter out = response.getWriter(); |
返回内容形式 |
response.setContentType("text/html"); |
返回的编码 |
response.setCharacterEncoding("UTF-8"); |
页面重定向 |
response.sendRedirect("index.jsp"); |
浏览器端保存cookie对象 |
response.addCookie() |
|
|
5.7.session对象
session 会话 浏览器和服务器通信 当浏览器关闭的时候会话结束
当浏览器第一访问服务器的时候就会产生一个会话
保存会话信息 |
session.setAttribute("uname","abc"); |
获取会话信息 |
session.getAttribute("uname"); |
5.8.application对象
application 应用 tomcat启动的时候整个项目就是一个应用
当把值存入应用中,只有当tomcat关闭的时候才销毁
保存应用信息 |
application.setAttribute("app","appInfo"); |
获取应用信息 |
application.getAttribute("app"); |
5.9.JSP中的四个域对象
四个域度对象
pageContext page域
request request域
session session域
application context域
1.域对象做用
保存数据和获取数据,用于数据共享
2.域对象方法
setAttribute("name",Object)保存数据
getAttribute("name")获取数据
removeAttribute("name")消除数据
域对象的做用范围
page域 :只能在当前jsp页面中使用(当前页面)
request : 只能在同一个请求中使用(转发)
Session : 只能在同一个会话(session对象)中使用(私有的)
context : 只能在同一个web应用中使用(全局的)
5.10.JSP的最佳实践
Servlet技术:开发动态资源。是一个java类,最擅长写java代码
JSP技术:开发动态资源,经过java代码最擅长输出html代码
一个在web项目中涉及到的逻辑:
1.接收参数
2.处理业务逻辑
3.显示数据到浏览器
4.跳转到其余页面
最佳实践中,对上述逻辑进行分工,由Servlet和JSP联合完成
Servlet:
1.接收参数
2.处理业务逻辑
3.把结果保存到域对象中
4.跳转到jsp页面
JSP:
1.从域对象中取出数据
2.把数据显示到浏览器
Servlet的数据-->JSP页面
6.EL表达式
6.1.EL表达式的做用
EL表达式也是用在html页面中的,目的是简化JSP操做,代码。
在最佳实践中,总结得出JSP中尽可能不要写java代码,最好的方法就是不写,因此的逻辑所有放到Servlet中,全部的数据展现放在JSP中
JSP的核心语法: jsp表达式 <%=%>和 jsp脚本<% %>。
如今使用EL表达式来替换到JSP的表达式
EL表达式的做用:向浏览器输出”域对象中的“变量值或表达式计算的结果!,注意必定要是域对象中的
语法:${变量或表达式}
6.2.EL语法
1.输出基本数据类型便变量
1.1.从四个域获取
输出普通字符串: ${name}
若没有指定域,则域的搜索前后顺序: pageScoep / requestScope / sessionScope / applicationScope
1.2.指定域获取
${pageScope.name},在pageScope域中查找name
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试jsp文件</title>
</head>
<body>
<%
String name = "roso";
pageContext.setAttribute("name",name,PageContext.REQUEST_SCOPE);
%>
<br>
EL表达式:${requestScope.name};
<%--
${name}等价于pageContext.findAtribute("name")
--%>
</body>
</html>
2.输出对象的属性值
输出对象属性: ${student.name} 注意: .name 至关于 .getName()方法
若是咱们定义了一个Student类,并定义了name成员变量,这个时候能够经过${student.name}来获取name值
点 . 方法是实际上是调用getXX()方法
3.输出集合对象
集合对象有List和Map
输出List集合: ${list[0].name } 注意: [0] 至关于 get(下标)方法
输出map集合: ${map[key].name} 注意: [key]至关于get(key)方法
中括号[]实际上是调用get
EL表达式没有遍历功能,可是能够结合标签使用遍历
4.EL表达式计算
表达式中须要注意的是字符串判空的一种方法${empty name}<br>
示例代码:
<%@ page import="servers.Student" contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<html>
<head>
<title>测试IE表达式</title>
</head>
<body>
<%--1.EL输出对象的属性--%>
<%
//保存数据
Student student = new Student("eric", 20);
//放入域中
pageContext.setAttribute("student",student);
%>
<%--2.EL输出集合List对象--%>
<%
//List
List<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",20));
list.add(new Student("luck",38));
//List放到域中
pageContext.setAttribute("list",list);
%>
<%--3.EL输出集合Map对象--%>
<%
//Map
Map<String,Student> map = new HashMap<String, Student>();
map.put("100",new Student("mark",20));
map.put("101",new Student("maxwell",30));
map.put("102",new Student("Eric",40));
//放入域中
pageContext.setAttribute("map",map);
%>
<%--3.EL表达式--%>
<%--3.1.算术表达式--%>
${10+5}<br>
<%--3.2.比较运算--%>
${10>5} <br>
<%--3.3.逻辑运算--%>
${true && false} <br>
<%--3.4.判空,null或空字符串--%>
判断null:${name==null}<br>
判断空字符串:${name==""}<br>
判空: ${name==null || name==""}<br>
判空的另外一个种写法: ${empty name}<br>
<%--1.使用EL获取对象--%>
<%--实际调用student的getName方法获取的值--%>
获取student的name属性值:${student.name}
<%--${student.name}的点至关于调用getXX()方法--%>
<br>
<%--2.使用EL获取List对象--%>
list对象:${list} <br>
获取list的第一个对象:${list[0]} <br>
获取list的第一个对象的name和age属性:${list[0].name} - ${list[0].age}
<br>
<%--${list[0]}等价于(ListpageContext.findAttribute("list)--%>
<%--${list[0]}的中括号至关于调用get()方法--%>
<%--3.使用EL获取Map对象--%>
获取Map对象:${map}<br>
获取key=100的值:${map['100'].name} - ${map['100'].age}
</body>
</html>
7.JSP标签
7.1.JSP标签的做用
咱们使用EL表达式来替换JSP的表达式,可是JSP还有一个常常会使用的语法,就是JSP脚本,出于和EL表达式一样的目的,咱们使用标签来替代JSP脚本,以达到简化JSP页面的目的
因此JSP标签做用:替换JSP脚本
主要功能有:
1.路程判断(if,for, 循环)
2.跳转页面(转发,重定向)
3.…………
7.2.JSP标签的分类
JSP的标签也分为几种类型的
1.内置标签:,也叫动做标签,不须要在jsp页面中导入的标签
2.JSTL标签:须要在jsp页面中导入的标签
3.自定义标签:开发者自行定义,须要在jsp页面导入标签
7.3.动做标签
转发标签:
参数标签:
包含标签:
包含标签的原理:
包含与被包含的页面先各自翻译成java源文件,而后在运行时再合并在一块儿。(先翻译再合并),动态包含,使用include指令包含是静态包含
静态包含 VS 动态包含
1.语法不一样
静态包含语法:<%@inclue file="被包含的页面"%>
动态包含语法:
2.参数传递不一样
静态包含不能向被包含页面传递参数
动态包含能够向被包含页面传递参数
3.原理不一样
静态包含: 先合并再翻译
动态包含: 先翻译再合并
7.4.JSTL标签
JSTL的全名是:Java Standard Tag Libarary ---java标准标签库
java标准标签库有五类,经常使用的是前三类
标签核心库(c标签库) 每天用
国际化标签(fmt标签库)
EL函数库(fn函数库)
xml标签库(x标签库)
sql标签库(sqp标签库)
7.5.使用JSTL标签的步骤
1.导入jstl支持的jar包(标签背后隐藏的java代码)
把包放在WEB-INF下的lib包
2.使用tablib指令导入标签库
<%@taglib prefix="简写" uri="tld文件的uri名称" %>
uri从jstl.jar包下的META-INF下的tld文件中查找,把uri的值复制过来,prefix的值也是在tld中查找
3.在jsp中使用标签
核心标签库的重点标签
保存数据:
<c:set></c:set>
获取数据:
<c:out value=""></c:out>
单条件判断:
<c:if test=""></c:if>
多条件判断:
<c:choose></c:choose>
<c:when test=""></c:when>
<c:otherwise></c:otherwise>
循环数据:
<c:forEach></c:forEach>
<c:forTokens items="" delims=""></c:forTokens>
重定向:
<c:redirect></c:redirect>
代码示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>JSTL核心标签</title>
</head>
<body>
<%--使用标签--%>
<%--1.set标签:保存数据(保存到域中),默认保存到page域中,能够指定--%>
<c:set var="name" value="Eric" scope="request"></c:set>
${name}<br>
${requestScope.name}<br>
<%--2.out标签:获取数据(从域中),当value值为null时,可使用default指定的默认值,escapeXml标明默认值是原样输出仍是转化为以后再输出,默认为true,表示原样输出--%>
<%--双引号内虽然是name,可是现实的是字符串name,由于是在双引号内--%>
<c:out value="name"/>
<%--调用name的值正确写法--%>
<c:out value="${name}" default="<h3>标题3</h3>" escapeXml="false"/><br>
<%--3.if标签:单条件判断,若是test里面的EL表达式为真,则运行if包含的代码--%>
<c:if test="${10>5}">
条件成立
</c:if>
<%--4.choose标签+when标签+otherwirse标签:多条件的判断--%>
<c:set var="score" value="86"></c:set>
<c:choose>
<c:when test="${score>=90 && score<=100}">
优秀
</c:when>
<c:when test="${score>=80 && score<=90}">
良好
</c:when>
<c:when test="${score>=70 && score<=80}">
通常
</c:when>
<c:when test="${score>=60 && score<=70}">
及格
</c:when>
<c:otherwise>
不及格
</c:otherwise>
</c:choose>
<br>
<%--5.forEach:循环--%>
<%
//List
List<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",20));
list.add(new Student("luck",38));
//List放到域中
pageContext.setAttribute("list",list);
%>
<%
//Map
Map<String,Student> map = new HashMap<String, Student>();
map.put("100",new Student("mark",20));
map.put("101",new Student("maxwell",30));
map.put("102",new Student("Eric",40));
//放入域中
pageContext.setAttribute("map",map);
%>
<%--<c:forEach
begin="从哪一个元素开始遍历,默认从0开始,能够不写"
end="到哪一个元素结束,默认到最后一个元素,能够不写"
step="步长,默认是1,能够不写"
var="每一个元素的名称"
items="须要遍历的数据(集合)"
varStatus="当前正在遍历的元素的状态对象(count属性:当前位置,从1开始)"/>--%>
<%--遍历list--%>
<c:forEach begin="0" end="2" step="1" items="${list}" var="student" varStatus="varSta">
姓名:${varSta.count}--${student.name}--年龄:${student.age}<br>
</c:forEach>
<%--遍历Map--%>
<c:forEach items="${map}" var="entry">
${entry.key}--姓名:${entry.value.name}--年龄:${entry.value.age}<br>
</c:forEach>
<%--6.forToken标签:循环特殊字符串--%>
<%
String str = "java-php-net-平面";
pageContext.setAttribute("str",str);
%>
<c:forTokens items="${str}" delims="-" var="s">
${s}<br>
</c:forTokens>
<%--7.重定向--%>
<c:redirect url="http://www.baidu.com"/>
</body>
</html>
8.自定义标签
8.1.引入
当现有的标签没法知足咱们的需求时,就须要本身开发一个适合的标签
例如,须要向浏览器输入当前客户端的IP地址,虽然用java程序是能够的,可是用标签是没有这个功能的,如今,咱们来自定以这个标签
8.2.第一个自定义标签开发步骤
1.编写一个普通的类,继承SimpleTagSupport类,叫作标签处理器类
/**
* 标签处理类
* 1.继承SimpleTagSupport
*/
public class ShowIpTag extends SimpleTagSupport {
/**
* 2.覆盖doTag方法
*/
@Override
public void doTag() throws JspException, IOException {
//向浏览器输出客户的IP地址
PageContext pageContext = (PageContext)this.getJspContext();
HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
String ip = request.getRemoteHost();
JspWriter out = pageContext.getOut();
out.write("使用自定义标签输出客户的IP地址:"+ip);
}
}
2.在web项目的WEB-INF目录下创建net.tld文件,这个tld叫标签的声明文件(参考核心标签库的写法)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<!--标签库的版本-->
<tlib-version>1.1</tlib-version>
<!--标签库前缀-->
<short-name>net</short-name>
<!--tld文件的惟一标记-->
<uri>http://gz.itcast.cn</uri>
<!--一个标签的声明-->
<tag>
<!--标签名-->
<name>ShoeIp</name>
<!--标签处理器类的全名-->
<tag-class>tag.ShowIpTag</tag-class>
<!--输出标签体内容格式-->
<body-content>scriptless</body-content>
</tag>
</taglib>
3.在jsp页面的头部导入自定义标签库
<%@taglib prefix="net" uri="http://gz.itcast.cn" %>
4.在jsp中使用自定义标签
8.3.自定义标签的执行过程
问题: http://localhost:8080/hello/tag.jsp 如何访问到自定义标签?
前提:tomcat服务器启动时,加载到每一个web应用,加载每一个web应用的WEB-INF目录下的全部文件,如web.xml, tld文件
访问步骤:
1.访问tag.jsp资源
2.tomcat服务器把jsp文件翻译成java源文件-->编译class-->构造类对象-->调用_jspService()方法
3.检查jsp文件的taglib指令,是否存在名为http://gz.itcast.cn的tld文件,若是没有,则报错
4.上一步已经读取到net.tld文件
5.在tag.jsp中读到,到net.tld文件中查询是否存在为ShoeIp的标签
6.找到对应的标签,则读到内容
7.获得tag.ShowIpTag
8.构造ShowIpTag对象,而后调用ShowIpTag里面的方法
8.4.自定义标签处理类的生命周期
标签处理器本质上实现的仍是SimpleTag接口,只是对里面的方法进行了重写。
SimpleTag接口:
void setJspContext(JspContext pc)
设置pageContext对象,传入pageContext(必定调用)
void setParent(JspTag parent)
设置父标签对象,传入父标签对象,若是没有父标签对象,则调用此方法。经过geetParent()方法获得父标签对象
void setXX(值)
设置属性值
void setJspBody(JSpFragment jspBody)
设置标签体内容。标签提内容封装到JspFragment中,而后传入JspFragment对象,经过getJspBody()方法获得标签体内容,若是没有标签体内容,则不会调用此方法
void doTag()
执行标签时调用的方法(必定会调用)
8.5.自定义标签的做用
1.控制标签体内容的是否输出
2.控制标签余下内容是否输出
3.控制重复输出标签体内容
4.改变标签体内容
5.带属性的标签
//1.声明属性的成员变量
private Integer num;
//2.关键点: 必须提供公开的setter方法,用于给属性赋值
public void setNum(Integer num) {
this.num = num;
}
自定义标签的做用代码示例:
/**
* 标签处理器类
*/
public class TagDemo extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
System.out.println("执行了标签");
/**
*1. 控制标签内容是否输出
* 输出:调用jspFrament.invoke();
* 不输出:不调用jspFrament.invoke();
*/
//1.1.获得标签体内容
JspFragment jspBody = this.getJspBody();
//执行invoke方法:会把标签体的内容输出到指定的Writer对象
//1.2.往浏览器输出,writer为null就是默认往浏览器输出
// JspWriter out = this.getJspContext().getOut();
// jspBody.invoke(out);
jspBody.invoke(null);//等价于上面的两行代码
/**
* 3.控制重复输出标签体内容
* 方法:执行屡次jspBody.invoke()方法
*/
for (int i=1; i <= 5 ; i++) {
jspBody.invoke(null);
}
/**
* 4.改变标签提内容
*/
//4.1.建立StringWriter临时容器
StringWriter sw = new StringWriter();
//4.2.把标签提内容拷贝到临时容器
jspBody.invoke(sw);
//4.3.从临时容器中获得的标签
String content = sw.toString();
//4.4.改变内容
content = content.toLowerCase();
//4.5.把改变的内容输出到浏览器
//不能使用jspBody.invoke()来输出,由于标签体内的内容并无改变,改变的是容器里面的
this.getJspContext().getOut().write(content);
/**
* 2.控制标签余下内容是否输出
* 输出:什么都不作就会默认输出
* 不输出:抛出有SkipPageException()异常则不输出
*/
throw new SkipPageException();
}
}
8.6.输出标签体内容格式
JSP:在传统标签中使用。能够写和执行jsp的java代码
scriptless:标签体不能够写jsp的java代码
empty:必须是空标签
tagdependent:标签体内容能够写jsp的java代码,但不会执行
9.JavaBean
JavaBaen,咖啡豆,是一种开发规范,能够说是一种技术
JavaBaen就是一个普通的java类,只要符合如下规定才能称之为javaBean:
1.必须提供无参构造方法
2.类中属性都必须私有化
3.该类提供公开的getter和setter方法
javaBean的做用:
用于方法数据,保存数据
方法javaBean只能使用getter和seetter方法
javaBean的使用场景:
1.项目中用到实体对象(entity)符合javaBean规范
2.EL表达式访问对象属性,${student.name}滴啊用getName()方法,符合javaBean规范
3.jsp标签中的属性赋值,setNum(Integet num)。符合javaBean规范
4.jsp页面中使用javaBean,符合javaBean规范
javaBean在jsp页面中的使用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp页面中使用javabean</title>
</head>
<body>
<%--建立对象,使用无参构造器--%>
<jsp:useBean id="stu" class="servers.Student"/>
<%--赋值--%>
<jsp:setProperty name="stu" property="name" value="jacky"/>
<%--获取--%>
<jsp:getProperty name="stu" property="name"/>
</body>
</html>