JavaWeb JSP

JSP(Java Server Pages)是由sun公司定义的一种用于开发动态web资源的技术,遵循JSP/Servlet规范。相当于能够执行Java语句的Html页面,从而能够输出动态内容,本质上就是一个封装好的Servlet

JSP原理

JSP文件无法被直接执行,其遵循以下执行步骤:
(1)服务器引擎将JSP内容翻译成纯Java代码,并进行编译(可以查看目录/work/Catalina/localhost/项目名/org/apache/jsp,里面有对应的.java.class文件)
(2)执行编译后生成的.class文件
(3)当.class文件存在且JSP内容没被修改时,则不会执行上面步骤,而是直接执行.class文件

JSP语法

脚本元素

主要分有三种:
1.脚本段:<% java代码 %>,可以放各种java代码,这里面的变量相当于方法内部的临时变量
2.声明段:<%! 变量/方法声明 %>,可以声明多个变量和方法,用分号隔开,这里面的变量相当于类的成员变量,在当前整个JSP页面中有效
3.表达式:<%=表达式%>,输出一个表达式结果,其本质就相当于out.print(表达式),所以后面不要有分号
注:
输出方式有两种,一个是表达式输出,还有一个是通过out.print()输出,从上面可以知道表达式输出的原理就是一个包装好的out.print()方法,因此对于输出表格的一列,前者可能是:<td><%=xxx%></td>,而后者则是:out.print("<td>xxx</td>"),可以看出前者很好的将HTML代码和JSP代码分离,而后者不行,所以尽量使用第一种方法

注释

主要分为以下几种:
1.<!-- -->:显式注释,直接用HTML代码的注释,前端可见
2.////* */:隐式注释,java代码自带的注释,只能在脚本段(<% %>)中用,前端不可见
3.<%-- --%>:隐式注释,JSP自带的注释,前端不可见

三个指令

指令语法:<%@指令 属性1=值 属性2=值 ...%>,主要指令有以下几个:

1.page指令

用于定义JSP的全局属性,其下有常用属性如下:
(1)contentType:有设置MIME类型(浏览器的打开方式,一般设置成html),举例:

<%page contentType="text/html; charset=GBK" %>  //设置编码

(2)pageEncoding:设置JSP引擎的翻译编码
(3)import:导包属性,导入可使用的java类,是page下唯一一个可以多次设置的属性,如果要导入多个包,则用逗号隔开,举例:

<%@page import="java.util.*,java.net.Socket"%>

(4)errorPage:当原来的JSP页面出现错误时,将会自动跳转到指定页面,默认是相对路径,如果以/开头则代表从项目根目录开始的路径,举例:

<%@ page errorPage="error.jsp" %>

(5)isErrorPage:是否为错误页面,默认是false,如果设置为true则会多一个Throwable对象exception,可以用来查看错误信息,举例:

<%@ page isErrorPage="true" %>
...
<%=exception.getMessage()%>

(6)isELIgnored:是否忽略EL表达式,默认为false

2.include指令

用于在JSP页面中静态包含一个文件,可以是JSP、HTML、TXT文件等,也可以是一段Java代码,使用该指令的JSP页面在翻译前会自动插入包含的文件或者代码,其中该指令有两种语法:

<%@include file="xxx.html" %>  //第一种
<jsp:include page="xxx.jsp" />  //第二种,不是指令方法,属于动作元素

前者为静态包含文件,其会在翻译JSP之前就把包含文件的内容加进来,即合并成一个文件,然后一起翻译、编译和执行;后者为动态包含,其会先翻译、编译和执行原来的JSP文件,当执行到包含文件的语句时,则会对该文件也进行翻译、编译和执行,并且还可以在包含文件时传入参数,举例:

<jsp:include page="xxx.jsp">  //按成对标签情况结尾没有斜杠
  <jsp:param name="xxx" value="xxx" />  //单标签情况结尾用斜杠结束
  ...
</jsp:include>
3.taglib指令

在页面中导入JSTL标签库,替换JSP中的java代码片段,包括if、forEach、import等

附:JSTL标签

Java Server Page Standard Tag Library,JSP标准连接库,主要用于简化Java代码,导入库方式:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  //导入标签库,并取名为c

有以下核心标签库:
(1)set:声明变量,有varvaluescope三个属性
(2)out:输出,有valuedefault属性
(3)remove:移除变量,有var属性,使用举例:

<c:set var="name" value="${1}" scope="page"/>  //name=1
<c:out value="${name}"/>
<c:remove var="name"/>
<c:out value="${name}" default="nothing"/>  //name不存在,输出nothing

(4)if:判断语句,当test属性的内容为true即输出,举例:

<c:if test="${6>5}">
fasfdsgs
</c:if>

(5)choose:相当于switch语句,里面用when标签来选,举例:

<c:set var="score" value="${61}" />
<c:choose>
    <c:when test="${score<60 && score>=0}">不及格</c:when>
    <c:when test="${score>=60 && score<80}">及格</c:when>
    <c:when test="${score>=80}">优秀</c:when>
    <c:otherwise>其他</c:otherwise>
</c:choose>

(6)forEach:循环用,有varbeginendstep等属性,举例:

<c:forEach var="i" begin="1" end="10" step="2">
    ${i}
</c:forEach>

该标签下还有items属性,主要用于存放迭代器和数组等,还有varStatus属性代表给迭代器取名,则该迭代器下有自带的四个属性(通过getter方法调用):index(从0开始的索引),count(从1开始的计数),first/last(是否为第一个/最后一个),举例:

<%
    ArrayList li = new ArrayList();
    li.add("aaa");
    li.add("bbb");
    li.add("ccc");
    String[] s = { "dsa", "Fsdg", "Hrhe" };
    request.setAttribute("list", s);
%>
<table border="1">
    <c:forEach items="${list}" var="l" varStatus="vs">
        <tr>
            <td>${l}</td>
            <td>${vs.index}</td>
            <td>${vs.count}</td>
            <td>${vs.first}</td>
            <td>${vs.last}</td>
        </tr>
    </c:forEach>
</table>

结果为:
dsa     0   1   true    false
Fsdg    1   2   false   false
Hrhe    2   3   false   true

六个动作

与指令元素不同,动作元素在请求处理阶段起作用,使用XML语法,语法格式:

<jsp:动作 属性=值 ... />  //格式1
<jsp:动作 属性=值 ... >...</jsp:动作>  //格式2

可以看出在格式2中可以多个动作元素进行嵌套使用。常用的有以下几种:
1.<jsp:include page="" />:动态包含文件
2.<jsp:param name="" value="" />:设置请求参数值,相当于url?name=value
3.<jsp:forward page="" />:跳转到页面,为服务端跳转,假如后面还有语句,则不会执行
4.<jsp:useBean id="实例化对象" class="对象对应的包.类" scope="对象使用范围" />:用于创建javabean对象,举例:

<jsp:useBean id="user" class="cn.aaa.User" scope="page" />

实质上就相当于:

<%
    User user = new User();
%>

5.<jsp:setProperty name="javabean对象" property="属性" />:设置javabean对象属性值,其中有四种方法设置:

<jsp:setProperty name="XXX" property="*" />  //根据参数名称自动进行设置,利用了反射机制,通过传递的参数找到对应方法
<jsp:setProperty name="XXX" property="yyy" />  //指定属性
<jsp:setProperty name="XXX" property="yyy" param="zzz" />  //将指定参数的值给指定属性
<jsp:setProperty name="XXX" property="yyy" value="zzz" />  //设置指定值给指定属性

第一种方法将根据前端传来的参数名称自动匹配,举例:
javabean对象:

public class User {
    String name;
    String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

表单数据:

<form action="index.jsp" method="post">
    <input type="text" name="name"> 
    <input type="password" name="password">
    <input type="submit" value="submit">
</form>

jsp中:

<jsp:useBean id="u1" class="com.aaa.User" />
<jsp:setProperty property="*" name="u1"/>
<jsp:getProperty property="name" name="u1"/>
<jsp:getProperty property="password" name="u1"/>

结果将会自动设置name和password的值并获取。
6.<jsp:getProperty name="javabean对象" property="属性"/>:获取指定对象属性

九大内置对象

Java中一般使用对象前需要进行实例化,而下面的9个对象则可以无需实例化直接调用,即内置对象

1.pageContext

当前页面上下文,其可以获得request/session等对象,因此也可以操作requset/session/application的数据,常用方法:
(1)getRequest():获取当前页面的request对象,其他几个对象也都可以通过相应的get方法获得,如:getResponse()getServletContext()getOut()
(2)setAttribute():设置属性值,还有对应的getAttribute()removeAttribute(),但和其他的属性操作方法不同的是,这三个方法可以比原来都多1个参数,用来设置作用域,举例:

pageContext.setAttribute("aaa", "bbb", pageContext.APPLICATION_SCOPE);  //提供了四个作用域常量,分别对应数字1-4

(3)findAttribute():和getAttribute()一样是获取属性,但是该方法可以无视作用域,依次从page->request->session->application里面查找,找到则取值并结束查找
(4)forward():跳转
(5)include():包含

2.request

常用方法:
(1)getParameter():接收表单参数
(2)setCharacterEncoding(编码):上面的方式直接接收数据容易出现乱码,于是最好通过该方法先设置接收编码,举例:

<% String name = request.getParameter("username"); %>

(3)getParameterValues():当遇到像复选框这样有多个参数的情况,上面的方法只能接收到第一个参数,因此需要使用该方法来接收一组参数,返回的是个数组
(4)getRemoteAddr():取得客户端的IP地址
(5)getCookies():获取所有cookie对象,返回一个cookie数组,举例:

public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    int i = 0;
    Cookie cs[] = request.getCookies();
    for (Cookie c : cs) {
        System.out.println(c.getName() + ":" + c.getValue());
    }
    response.addCookie(new Cookie("name", "" + i++));
}

(6)getSession():返回一个HttpSession对象

3.response

常用方法:
(1)setHeader(name, value):设置头信息的内容,获取头信息则可以用getHeader(name),如果要获取所有头信息名字,则用:getHeaderNames(),其中有个定时跳转的属性为refresh,举例:

response.setHeader("refresh","1");  //1秒刷新一次
response.setHeader("refresh","2;URL=xxx.jsp");  //2秒后跳转到xxx.jsp,此处为客户端跳转

(2)sendRedirect(url):重定向到页面,为客户端跳转,并且如果后面还有语句,则会在后面的语句都执行完后才进行跳转,也可以通过设置响应头来实现。
(3)addCookie(cookie):给客户端设置cookie,需要建立个Cookie对象来设置cookie,举例:

Cookie c1 = new Cookie("name","aaa");
Cookie c2 = new Cookie("password","bbb");
response.addCookie(c1);
response.addCookie(c2);

(4)setContentType(type):设置内容的返回类型

4.session

对于服务器来说,每一个上网者是通过session id来区分的,而该id是用户第一次连接到服务器时服务器自动分配的,常用于系统登录中。有以下常用方法:
(1)isNew():是否为新session
(2)getId():返回session id
(3)invalidate():让session失效

5.application

即Servlet中的ServletContext,常用方法:
(1)getRealPath():获取虚拟目录对应的真实路径
注:
一般很少直接用application,而用getServletContext()来表示application

6.config

ServletConfig对象

7.out

相当于PrintWriter对象,即输出页面信息用的

8.page

当前Servlet实例对象,即this

9.exception

当设置isErrorPagetrue时才存在,可以输出错误信息

四大域对象

属性范围即设置的属性可以在经过多少个页面后仍可访问的范围,范围越大,越影响性能

1.page

仅能在当前页中取得,通过pageContext来设置

2.request

在一次服务器的跳转中有效,所以只要是服务器跳转,就可以将属性一直传递(所以使用超链接跳转则属性消失)

3.session

一个用户设置的内容,只要和该用户相关的页面都可访问,所以不论怎么跳转都可以取到值,但是新开一个浏览器,则无法取得属性

4.application

整个服务器上设置的属性,所有人都可以访问,但是服务器一旦关闭,该属性也会随之消失,并且因为范围太大,影响效率,且不安全,尽量少用

属性操作

对于上面的几种属性范围,都提供了以下的几个属性操作方法:
(1)setAttribute(name, value):设置属性
(2)getAttribute(name):获取属性,返回Object对象,需要进行强转
(3)removeAttribute(name):删除属性
使用举例:

<%
  pageContext.setAttribute("name", "aaa");  //设置page属性
%>

EL表达式

expression language,即表达式语言,用于简化java代码,是JSP中获取数据的一种规范

格式及原理
格式一——获取域对象数据
${内容}

举例:

<%=request.getAttribute("aaa") %>
<%=session.getAttribute("aaa") %>

那么上面两个语句都可以用下面这一句来表示:

${aaa}

但有点不同的是如果获取的数据不存在,则不是null,而是空字符串。从以上可以发现EL表达式的底层代码差不多就是:

out.print(pageContext.findAttribute("aaa") != null?pageContext.findAttribute("aaa"):"");
格式二——获取数据属性
${对象.xxx}
${对象["xxx"]}  //用单引号也可以

对于获取的数据如果是对象,则可以用.属性或者["属性"]来获取属性,如果获取的属性还是个对象,还能继续用该方法继续往下获取属性...但这些表达式获取属性的本质是调用了对象的getter方法,而并非直接调用属性。
两种获取属性区别:
前者能做到的,后者都能做到,但是在比如列表索引下标时,只有后者能够做到

格式三——判空运算
${ empty 内容}

判断内容是否为空,是则为true,举例:

<%
    request.setAttribute("l1", new ArrayList());
    request.setAttribute("l2", new String[10]);
    request.setAttribute("l3", "");
%>
${empty l1}  //空列表,为true
${empty l2}  //10个null的数组,为false
${empty l3 ? "空字符串":"非空字符串"}  //空字符串
格式四——引用隐式对象
${隐式对象.内容}

可以获得指定对象的数据,举例:

<%
    pageContext.setAttribute("aaa", "aaa", 1);
    pageContext.setAttribute("aaa", "bbb", 2);
    pageContext.setAttribute("aaa", "ccc", 3);
    pageContext.setAttribute("aaa", "ddd", 4);
%>
${applicationScope.aaa}  //指定获取application对象的aaa,因此输出ddd
${param.aaa}  //url?aaa=asd,则输出asd

其中其包括11个隐式对象:
(1)pageContext
(2)pageScope:页面范围的数据
(3)requestScope:请求范围的数据
(4)sessionScope:会话范围的数据
(5)applicationScope:应用范围的数据
(6)param:一个请求参数,相当于request.getParameter()
(7)paramValues:重名请求参数(如多选框)
(8)header:请求消息头
(9)headerValues:重名请求消息头
(10)initParam:web.xml的全局参数
(11)cookie:cookie对象的name

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • JSP总结(经典) day1 JSP 定义: 1)Java Server Page, Java EE 组件,本...
    java日记阅读 3,434评论 0 13
  • 1.什么是JSP (1)jsp全称是Java Server Pages,它和Servlet技术一样都是sun公司定...
    yjaal阅读 3,646评论 5 99
  • 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Se...
    chinariver阅读 5,613评论 1 49
  • 其他更多java基础文章:java基础学习(目录) 本章内容较多,全部认真看完可能需要一小时以上,建议边看边做笔记...
    Hiwayz阅读 1,311评论 0 10
  • 一、jsp定义及作用 JSP技术使用Java编程语言编写类XML的tags和scriptlets,来封装产生动态网...
    yzw12138阅读 1,229评论 0 0