五、JSP

Servlet开发的Web存在的缺陷
  • 使用Servlet程序进行结果的展示麻烦,需要使用IO流响应结果
  • 页面样式改动需要重新编译和部署,重启服务器

JSP — Java server page

  • JSP是Servlet的升级版本,运行于服务器端端 Java页面技术,主要用于开发数据的展示功能
  • 创建Web项目 —> 在WebRoot创建jsp的文件,不要放在WEB-INF下,因为WEB-INF下的内容,不直接对外公开
  • JSP主要用于开发动态Web应用,且必须在服务器中才能运行
ServletJSP
开发继承HttpServlet(实现Servlet)接口
覆盖service方法
编写web.xml
创建 .jsp结尾的文件中
书写HTML+Java代码
修改需要重新编译、重新部署、重启服务器刷新页面即可
部署正常部署Web项目正常部署Web项目
访问http://localhost:端口/项目名/url-patternhttp://localhost:端口/项目名/jsp的相对路径
JSP执行原理
  • JSP的本质就是Servlet,JSP的运行依赖于服务器
  • 本质是一个servlet,JSP做数据的展示,从执行的效率上讲,相对比html效率要低
    • 翻译:tomcat服务器首先将请求的 JSP翻译成 .java文件
      • 翻译规则
        • HTML标签翻译成了 out.write(…);
        • 表达式脚本中的表达式翻译成out.print(…);
        • 声明脚本中的函数翻译成类中普通的方法,变量翻译成了成员变量
        • 普通脚本中的内容翻译成了方法内部的代码块
        • 普通脚本中声明的变量翻译成了局部变量
    • 编译:将翻译成的 .java文件,编译成 .class文件
    • 执行:最终执行的是 .class文件
JSP页面基本语法
  • 脚本元素:各个脚本语法之间都不允许嵌套,且脚本内不允许直接书写HTML标签

    • 表达式脚本:展示结果,可以将表达式脚本的结果作为HTML标签属性值
      • <%=表达式 => 表达式结束不能有分号
      1+1=<%=1+1 %><br>
      1/1=<%=1/1 %><br>
      1%1=<%=1%1 %><br>
      <%=1>0 %><br>
      <%="abc"=="abc" %>
    
    • 声明脚本:用于声明函数和变量
      • <%! 函数声明 / 变量声明 %> 声明脚本中不能调用函数,可以在表达式脚本中调用
    <%!
      //声明函数
      public int sum(int a,int b){
      	return a+b;
      }
      public java.util.Date getDate(){
        return new java.util.Date();
      }
      //声明变量
      int m = 10;
    %>
    //调用
    <%=sum(100,200) %>
    <%=m+n %>
    <%=getDate() %>
    
    • 普通脚本:用于书写普通的Java代码,如for循环、分支语句
      • <% Java代码 %> 普通脚本内不能嵌套其他脚本元素
    <%
      for(int i = 0;i < 10; i++){%>
    	  <%="hello world" %><br>
      <%}
    %>
    
  • 指令元素

    • 页面指令:书写和指定当前 JSP页面的基本配置信息
      • <%@ page 属性=值 %> 只能写在 JSP页面的第一行开始,可以写多个
    <%@ page
    pageEncoding="utf-8" //编码设置指令,必须写
    contentType="text/html;charset=utf-8" //可以省略 默认utf-8
      
    import="java.util.*,java.io.*" //相当于java中导包语句,多个可以用逗号连接
    
    errorPage="xxx.jsp"	//配合使用 如果访问出现异常,跳转到错误页面,地址栏不变
    isErrorPage="true"
      
    language="java" //默认值为java,指定当前的JSP页面支持的变成语言,目前只支持java
    
    isELIgnored="false"  //是否忽略EL表达式,默认为false,不忽略
      
    session="true"  //代表JSP翻译成Java的时候,是否主动创建session对象
    
    %>
    
    • 包含指令:将另一个 JSP页面,包含到当前的 JSP页面
    • <%@include file=“被包含页面路径” %>
      • 包含的是源文件,也称为静态包含,包含的文件的内容;在开发中需要注意两个页面之间变量名冲突的问题,最后包含页面也被包含页面会合并为一个 .java文件编译
    • 标签指令:在当前 JSP页面引入一个标签库
      • <%@taglib uri=“标签库路径” prefix=“别名 / 标签库前缀名” %>
  • 动作元素

    • 包含动作:动态包含,不包含源文件,是各个页面的执行结果拼接而成,所以不会出现变量名冲突部分
      • <jsp:include page=“被包含的路径” ></ jsp:include>
    • 转发动作:相当于Servlet中的请求转发
      • <jsp:forward page=“路径” ></ jsp:forward>
JSP页面九大隐含对象
  • 在服务器将 JSP翻译成 .java的时候,自动给我们创建的九个对象

  • request:相当于Servlet中的request作用域

  • response:相当于Servlet中的response对象

  • session:相当于Servlet中的session作用域,要使用session,必须保证页面指令session=true

  • application:相当于Servlet中的ServletContext作用域

  • pageContext

    • pageContext的作用域功能:

      • 仅限于当前的 JSP页面
      • pageContext.setAttribute(“name” ,value);
    • 操作其他作用域:

      <%   第三个参数为指定操作哪个作用域
      pageContext.setAttribute("name","P");
      pageContext.setAttribute("name","R",PageContext.REQUEST_SCOPE);
      pageContext.setAttribute("name","S",PageContext.SESSION_SCOPE);
      pageContext.setAttribute("name","A",PageContext.APPLICATION_SCOPE);
      %>
      pageContext:<%=pageContext.getAttribute("name") %><br>
      request:<%=request.getAttribute("name") %><br>
      session:<%=session.getAttribute("name") %><br>
      application:<%=application.getAttribute("name") %><br>
      
    • 从作用域中搜索命名属性:

      • pageContext.findAttribute(“name”); //按照作用域从小到大的顺序搜索命名属性,找到则返回,不再继续向下搜索;如果所有作用域都没搜索到,则返回null
  • out:一个输出流,相当于PrintWriter,可以向页面输出内容

  • config:相当于ServletConfig对象,封装了当前Servlet实现类对web.xml配置文件中的配置信息和获取web.xml默认对象

  • page:相当于this .

  • exception:只在isErrorPage="true"的页面存在,封装了捕捉到的异常信息对象

EL表达式
  • expression language是JSP页面用于展示结果的一种表达式语言,使用EL表达式可以操作作用域和一些表达式运算

  • EL表达式在开发中主要配合JSTL标签库来完成数据的展示

  • EL表达式的诞生是为了使 JSP页面的编码更加简洁,可以替换掉大部分脚本元素

  • 语法:${表达式} 在使用EL表达式的JSP页面要保证 isELIgnored=false

  • 基础应用

    		<h3>算数运算</h3>
    		1+2=${1+2 }<br>
    		
    		<h3>关系比较</h3>
    		1 &gt; 2=${1>2 } | ${1 gt 2 }<br>
    		1 &gt;=2=${1>=2} | ${1 ge 2 }<br>
    		1 &lt; 2=${1<2 } | ${1 lt 2 }<br>
    		1 &lt;=2=${1<=2} | ${1 le 2 }<br>
    		1 == 2=${1==2 } | ${1 eq 2 }<br>
    		1 != 2=${1!=2 } | ${1 ne 2 }<br>
    		${"a"=="a" }<br>
    		${"a"=="aa" }<br>
    		
    		<h3>逻辑运算</h3>
    		与:${1==1 && 1>1 } | ${1==1 and 1>1 }<br>
    		或:${1==1 || 1>1 } | ${1==1 or 1>1 }<br>
    		非:${!(1==1 && 1>1) } | ${not(1==1 && 1>1) }<br>
    
    		<h3>空值的判断</h3>
    		${m==null } | ${empty requestScope.m }
    
  • EL表达式操作作用域,主要是从作用域中取值

    request:${requestScope.name } | <%=request.getAttribute("name") %>  //等价
    session:${sessionScope.name } | <%=session.getAttribute("name") %>
    application:${applicationScope.name } | <%=application.getAttribute("name") %>
    pageContext:${pageScope.name } | <%=pageContext.getAttribute("name") %>
    
    • 按照范围从小到大搜索命名属性
    • 表达式脚本如果从作用域中找不到指定命名属性返回null,EL表达式如果从作用域中找不到命名属性,什么都不返回
    <%=pageContext.findAttribute("name") %> 	//基本等价
    ${name }<br> 	//根据范围从小到大搜索命名属性
    
    • 获取list集合指定元素属性值
    <%
    	List<String> strList = new ArrayList<String>();
    	strList.add("hang");
    	strList.add("yuan");
    	strList.add("kun");
    	request.setAttribute("strList",strList);
    %>
    
    ${requestScope.strList[1] }
    
    • 获取map集合指定元素属性值
    <%
    	Map<String,String> strMap = new HashMap<String,String>();
    	strMap.put("p1","hang");
    	strMap.put("p2","yuan");
    	request.setAttribute("strMap", strMap);
    %>
    
    ${requestScope.strMap["p1"] }		//根据键获取值
    
    • 获取作用域中自定义对象类型的属性值
      • 通过EL表达式获取自定义对象类型的属性值时,是通过调用属性对应的get方法获取的,规则是属性名首字母大写,前面拼接get来调用实体类中get方法;底层是由反射获取,所以注意实体类中的命名规范
    <%
    	Person person = new Person(1,"yuan","woman");
    	request.setAttribute("person",person);
    	
    	List<Person> personList = new ArrayList<Person>();
    	personList.add(person);
    	personList.add(new Person(1,"hang","man"));
    	request.setAttribute("personList", personList);
    %>
    
    	实体类中的toString:${requestScope.person }<br>
    	person中的值:${requestScope.person.name } | ${requestScope.person.sex }<br>
    	<!-- 取list集合中的自定义对象  作用域中属性名不重复的时候可以在EL表达式中-->
    	${personList[0] }<br> 	<!-- 实体类中的toString -->
        ${personList[0].name } | ${personList[0].sex }<br> <!-- 点的是类中的属性名 -->
    
    • 取map集合元素 —> ${ map[key] }
    <%
    			Map<String,String> strMap = new HashMap<String,String>();
    			strMap.put("一号","hang");
    			strMap.put("二号","yuan");
    			request.setAttribute("strMap",strMap);
    			Map<String,Person> personMap = new HashMap<String,Person>();
    			personMap.put("p1", new Person("hang","LoveMe"));
    			personMap.put("p2", new Person("yuan","LoveMe1"));
    			request.setAttribute("personMap", personMap);
    %>
    		 <h3>取Map集合元素(字符串)</h3>
    		 取所有元素:${strMap }<br>
    		 根据key取值:${strMap['二号'] }
    		 <h3>取map集合元素(自定义对象)</h3>
    		 ${personMap['p2'].username }
    
  • EL表达式中其他内置对象

    • pageContext:动态获取项目名
      • 表达式脚本<%=request.getContextPath() %>
      • ${pageContext.request.contextPath }
    • param:获取地址栏的请求参数和客户端表单的请求参数
      • ${param.name(请求参数的key) }相当于Servlet中的request.getParameter(key)
      • <%=request.getParameter(“username”) %>
    • paramValues:获取地址栏、表单请求的一组参数
      • ${paramValues.hobby[0] }
      • <%=request.getParameterValues(“hobby”)[0] %>
    • cookie:可以获取到客户端浏览器上保存的cookie
      • ${cookie }
      • 获取指定的cookie对象:${cookie.username.name }
      • 获取指定的cookie对象的value:${cookie.username.value }
      • 获取jsessionid:${cookie.JSESSIONID.value }
JSTL标签库
  • Java Standard Tag Library,JSP的标准标签库,主要作用是展示数据,与EL表达式配合使用

  • JSTL标签库包含:core核心标签库、fmt数据格式展示库、sql数据库操作、xml子库

  • 使用JSTL开发

    • 在项目中倒入jstl1.2.jar,myeclipse中的web项目默认集成了jstl的依赖jar包
    • 在使用JSTL标签库的JSP页面引入标签库
    uri指定标签库地址  prefix给标签库指定一个前缀名,没有强制约束,建议用c
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
    • 核心标签库core的使用

      • if:根据条件判断展示数据
      <c:if test="书写EL表达式,布尔类型" >内容</c:if>
      
      • choose:类似于Java中switch case
      <!-- 当满足指定when的条件,执行对应语句,都不满足执行otherwise -->
      	<c:choose>
      		<c:when test="${score<60 && score>0 }">不及格</c:when>
      		<c:when test="${score>=60 && score<90 }">良好</c:when>
      		<c:otherwise>优秀</c:otherwise>
      	</c:choose>
      
      • 遍历list集合
      <%
      	List<String> strList = new ArrayList<String>();
      	strList.add("hang");
      	strList.add("yuan");
      	
      	List<Person> personList = new ArrayList<Person>();
      	personList.add(new Person(1,"hang","man"));
      	personList.add(new Person(2,"yuan","woman"));
      	
      	request.setAttribute("strList", strList);
      	request.setAttribute("personList", personList);
      %>
      <!-- 遍历list集合,泛型是字符串 -->
      <c:forEach items="${strList }" var="s">
      	${s }<br>
      </c:forEach>
      <!-- 遍历list集合,泛型是自定义对象 -->
      <c:forEach items="${requestScope.personList }" var="p">
      	${p.id }|${p.name }|${p.sex }<br>
      </c:forEach>
      
      • 遍历Map集合
      <%
      		Map<String,String> strMap = new HashMap<String,String>();
      		strMap.put("one","hang");
      		strMap.put("two","圆");
      		Map<String,People> peopleMap = new HashMap<String,People>();
      		peopleMap.put("one",new People(1,"hang","man",new Date()));
      		peopleMap.put("two",new People(2,"yuan","women",new Date()));
      		request.setAttribute("strMap", strMap);
      		request.setAttribute("peopleMap", peopleMap);
      	%>
      	<h3>字符串泛型map</h3>
      	<c:forEach items="${strMap }" var="m">
      		${m }<br>
      		${m.key }|${m.value }<hr>
      	</c:forEach>
      	<h3>自定义对象泛型map</h3>
      	<c:forEach items="${peopleMap }" var="map">
      		${map.key }|${map.value }<br>
      		${map.value.id }|${map.value.name }|${map.value.sex }|${map.value.birthday }<hr>
      	</c:forEach>
      
      • 使用forEach标签实现分页的页码展示
      	<h3>实现分页页码</h3> <!-- begin指定循环初始值,end指定到几结束,var指定循环到变量,step指定循环到步长,默认为1 -->
      	<c:forEach begin="1" end="10" var="i" step="1">
      		<a href="">${i }</a>
      	</c:forEach>
      
      • forEach标签的其他属性:

        • step:遍历增长的步长;
        • varStatus:循环遍历的状态对象
        	<c:forEach begin="1" end="10" var='i' step="2" varStatus="stu">
        		${i }&nbsp;|
        		当前循环的下标:${stu.index }&nbsp;|
        		当前遍历的次数:${stu.count }&nbsp;|
        		是否是第一次遍历:${stu.first }&nbsp;|
        		是否是最后一次遍历${stu.last }<br>
        	</c:forEach>
        
      • set:向作用域中存入命名属性,默认存储到pageContext中

      <!-- var为命名属性名,value为命名属性值,scope为指定存入哪个作用域 -->
      	<c:set var="name" value="hang"></c:set>
      	<c:set var="name" value="hang" scope="request"></c:set>
      	<c:set var="name" value="hang" scope="session"></c:set>
      	<c:set var="name" value="hang" scope="application"></c:set>
      	pageContext:${pageScope.name }<br>
      	request:${requestScope.name }<br>
      	session:${sessionScope.name }<br>
      	application:${applicationScope.name }<br>
      
      <c:set scope="request" var="hello"> //将out流的输出结果存入作用域
          <%
          for(int i=0;i<10;i++){
            out.println("Hello World");
          }
          %>
      </c:set> //存
      
      • remove:移除作用域的命名属性
      <!-- var指定移除的命名属性名,scope指定从哪个作用域移除,不指定则删除所有作用域 -->
      <c:remove var="name"></c:remove>
      <c:remove var="ceshi" scope="request"></c:remove>
      
      • out:向页面输出结果,可以设置是否原样输出还是加标签效果输出
      	<c:out value="12345"></c:out><hr>
      	<c:out value="<h1>12345</h1>"></c:out>
      <!-- escapeXml是否原样输出内容,默认为true,原样输出 -->
      	<c:out value="<h1>12345</h1>" escapeXml="false"></c:out>
      
      • import:可以将另一个页面的结果导入到当前页面,类似于动态包含
      <c:import url="http://www.baidu.com"></c:import> 
      
      • url:可以生成一个代表路径(项目名)的字符串,还可以检测浏览器cookie是否被禁用,被禁用的话会自动完成URL的重写,相当于response.encodeURL()方法的作用
      <a href="<c:url value="/elList.jsp"></c:url>">链接</a> //自动获取项目名
      
      <c:set var="path">
      	<c:url value="/elList.jsp"></c:url>
      </c:set>
      <a href="${path }">链接</a> //配合set使用
      
      • redirect:相当于Servlet中的转发重定向
      <c:redirect url="xxx.jsp"></c:redirect>
      
    • 格式化展示日期标签,需要导入格式化日期标签库

    <!-- 格式化日期标签库 -->
    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
    <%
    		request.setAttribute("date", new Date());
    %>
    ${date }<br>
    <!-- value属性必须接受一个日期值 -->
    <fmt:formatDate value="${date }" pattern="yyyy-MM-dd HH:mm:ss" />
    
MVC
  • 是一种编程思想,人为的将Web项目分成了三层,实际开发中顺序通常为MCV
    • M:Modle,数据模型层;负责数据的处理和操作
      • 数据处理和操作:实体类、DAO、Service
      • 实现技术:JDBC、Mybatis、Hibernate
    • C:Controller,控制器层;接收请求并处理请求,向客户端响应结果;控制请求从哪来、到哪去。负责流程的跳转
      • 处理请求的Servlet
      • 实现技术:Servlet、Struts2、SpringMVC
    • V:View,视图层;负责与用户进行交互,负责数据的展示,向服务器提交收集到的数据
      • html、JSP
  • 分层开发优点:各司其职、解耦合、利于团队的协作开发,且分层后每层的复用性得到提示
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值