JSP

JSP本质是servlet.

jsp=第一个被访问时=> java => class => 执行

JSP中的脚本
<% %> service方法中
<%! %> 在jsp的类中
<%= %> service方法中,out.print()方法包裹

<%-- --%> 注释.被注释的内容 不会出现在java文件中. 
对比 <!-- --> 与 JSP注释.

//--------------------------------------------------------------------------------------------------
1.JSP中指令
page   指令
include指令
taglib 指令

功能:
page   : 描述页面的一些属性.
include: 静态包含指令
taglib : 导入标签指令

page :  <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
page指令用于指定页面一些基本属性.
language="java" 页面中使用的语言为java.
*import="java.util.*"  就是导包. 是所有属性中唯一一个可以在页面中出现多次的属性.
*pageEncoding="UTF-8" 页面保存到硬盘编码.
*contentType="text/html; charset=UTF-8" 发送给浏览器的编码 . 
以上两个码表最好一致. 但是一般设置一个属性即可.另外一个属性自动设置.
autoFlush="true" 如果缓冲区装满是否自动刷新到浏览器. 如果装满并没有选择自动刷新,那么会抛出异常.
buffer="8kb" 决定jsp输出缓冲区大小为8kb
errorPage="" 配置当前页面的错误页面
isErrorPage="false" 指定当前页面是否是一个错误页面
开发中,我们可以使用如下配置统一配置错误页面 比上面的方式要省事:
  <error-page>
<error-code>500</error-code>
<location>/page/B.jsp</location>
  </error-page>

extends="" 决定当前jsp的父类是谁.父类必须是servlet的子类.
info="" getServletInfo 刚方法的返回值.
isELIgnored="false"  决定当前页面能否使用 EL表达式. 默认值就是支持el.
session="true" 当前jsp页面是否可以直接使用session对象.默认值就是true.
//---------------------------------------------------------------------------------------------------------------------
include 静态包含指令`
include 属于静态包含 , 现将两个jsp的代码合并.然后在共同编译成一个java文件.在编译成class ,再执行.

因为会先合并代码,所以变量可以共享.
使用: <%@ include file="/include/B.jsp" %>  将该指令加入到需要引入的位置即可.

//---------------------------------------------------------------------------------------------------------------------
2.JSP中的9大内置对象
指的在jsp中不加以声明就可以直接使用的9个对象.

原理: 因为我们的代码是写在jsp对应java的service方法中的.所以在service方法中声明的变量,我们可以直接使用.

public void _jspService(HttpServletRequest 1>request, HttpServletResponse 2>response)
        throws java.io.IOException, ServletException {


    PageContext 3>pageContext = null;
    HttpSession 4>session = null;
    Throwable 5>exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
    if (exception != null) {
      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
    ServletContext 6>application = null;
    ServletConfig 7>config = null;
    JspWriter 8>out = null;
    Object 9>page = this;
//-----------------------------------------------------------------------------------------------------
对象名称              对象类型
request HttpServletRequest
response HttpServletResponse
session HttpSession
exception Throwable
application ServletContext
config ServletConfig

page Object  没用.
out JspWriter  用于向浏览器输出信息
pageContext PageContext 9大内置对象的首领.
//-------------------------------------------------------------------------------------------------------
1>.out 对象是jsp当中的输出对象.
代码:
out.print("a");
    response.getWriter().print("b");
    out.print("c");
    response.getWriter().print("d");
输出: bd ac 
原理:
在输出到浏览器时,会先把两个流合并,再输出.
合并时response的字符流在前.
JSPWriter在后. 所以不管代码书写顺序如何.最终
response流的内容总会在JSPwriter流的内容之前

结论: 在jsp中输出使用out(JSPWriter)输出,不要使用response.getWriter输出.


2> page对象 => 一般没有用.
page对象 指向的就是 this(当前jsp生成Servlet对象);
使用情况一般是在开发框架时,框架需要用到JSP对象,进行一些页面的操作时,将page对象传过去即可.
3> pageContext对象 => 大哥级
*本身是一个域对象. 在pageContext对象上有一个map. 这个Map就是Page域.
操作: 4个操作.
范围: 就只在当前页面中有用.
作用: 在jsp中应避免在页面上书写任何java代码.
//pageContext.setAttribute(name, value);
// pageContext.getAttribute(name);
//pageContext.removeAttribute(name);
//pageContext.getAttributeNamesInScope(scope);
*pageContext对象还可以操作其他3个域
目的就是为了方便.
pageContext.setAttribute("name", "applicationTom",PageContext.APPLICATION_SCOPE );
pageContext.setAttribute("name", "sessionTom",PageContext.SESSION_SCOPE );
pageContext.setAttribute("name", "requestTom",PageContext.REQUEST_SCOPE );
 
  //pageContext.getAttribute(name, scope);
  //pageContext.removeAttribute(name, scope);
  //pageContext.getAttributeNamesInScope(scope);
  //pageContext.findAttribute("name") 会从所有域中查找键. 从小到大
*持有其他8个内置对象的引用.根据这个对象可以获得其他8个内置对象
pageContext.getRequest();
    pageContext.getResponse();
    pageContext.getSession();
    pageContext.getServletContext();
    pageContext.getException();
    pageContext.getServletConfig();
    pageContext.getOut();
    pageContext.getPage();
//-------------------------------------------------------------------------------------------------------
3.JSP中的动作标签(了解)
动作标签出现的年代是在JSP model1 . 
#<jsp:forward page="/index.jsp"></jsp:forward>
<%
//request.getRequestDispatcher("").forward(request, response);
%>
*<jsp:include page="/index.jsp"></jsp:include>  ==>  将来可能会使用.
<%
//request.getRequestDispatcher("").include(request, response);
%>
上面的包含就是之前学习的request的请求包含. 这种包含也叫做动态包含.
动态包含的两个页面会分别编译成两个java,class.分别执行. 只是在最后输出时将输出结果合并.
所以页面中的变量不会共享.
//-----------------------------------------------------------------------------------
BeanUtils
功能: 将表单参数封装到User对象
//参数1: 填写User对象
//参数2: 填写需要封装到User对象的参数Map
BeanUtils.populate(u,request.getParameterMap());
注意: 表单的参数的键必须与Bean中属性名称对应

// BeanUtils 可以自动帮你转换8个基本数据类型. 如果遇到自定义类型需要转换.我们要自己写一个转换器并注册

1.自定义转换器
public class MyDateConverter implements Converter {
//参数2 : 待转换的类型传递进来. => 2012-12-12
// 转换好之后,使用返回值返回  =>  Date对象
//参数1:  告诉你要转换成什么类型的
public Object convert(Class arg0, Object arg1) {
//创建格式化器
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//使用格式化器将参数格式化成日期类型
try {
Date date = format.parse(arg1.toString());
//没出异常.就返回日期对象.
return date;
} catch (ParseException e) {
e.printStackTrace();
//出现异常返回null
return null;
}}}
2. 转换器注册
//注册我们自定义的转换器
//参数1 自定的转换器
//参数2 注册转换的类型
ConvertUtils.register(new MyDateConverter(), Date.class);
完成如上两步即可.
//--------------------------------------------------------------------------------------------------------------------------------------------------

JSTL标签

用于代替,简化页面中的java代码.
Java standard Tag Library   => java标准标签库
apache组织提供一套已经开发好的标签库.
这套标签库在javaee 5.0版本后已经纳入标准.(使用不需要导包)
该套标签库一共分为4个库:
core:核心库(用的最多的)****
fmt:格式化库(2个)
xml:xml的操作相关(废弃)
sql: 与数据库操作相关(废弃)
//-----------------------------------------------------------------------------------------------------------------------------
core库(重点:if choose foreach url):
1.在页面引入标签库
2.使用.

<%-- ------------------------------------------------------------------------ --%>
<%-- <c:if>(常用) 判断
test="${num1 > num2 }"  填写返回值为boolean的表达式
var="if"
scope="page" 域  将判断结果以var属性值为键放入该属性指定的域中.
--%>
<%
request.setAttribute("num1", 1000);
request.setAttribute("num2", 10000);
%>
<c:if test="${num1 > num2 }" var="if" scope="page" >
num1 厉害!
</c:if>
${pageScope.if}
<hr>
<%-- ------------------------------------------------------------------------ --%>
<%--  判断标签.支持if else形式
<c:choose>
<c:when>
test: 填写返回值为boolean的表达式
<c:otherwise>
--%>
<c:choose>
<c:when test="${num1 > num2 }">
num1 厉害!
</c:when>
<c:otherwise>
num2 厉害!
</c:otherwise>
</c:choose>
<hr>
<%-- ------------------------------------------------------------------------ --%>
<%--  <c:forEach>(常用) 遍历标签 
items="${requestScope.list}" 要便利的集合设置给该属性
var="abc" 每次遍历集合中元素 该属性值作为键放入page域
  varStatus="st" 每次遍历的状态,会封装成一个对象 以该属性值为键 放入page域
数数的功能
begin="1"  从几开始数  
end="100" 数到几
step="1" 每次数几个数
var="num" 将当前数的数以该属性值作为键放入page域
--%>
<%
List list  = new ArrayList();
list.add("tom");
list.add("jerry");
list.add("jack");
list.add("rose");

request.setAttribute("list", list);
 %>
 
 <table border="1">
<tr>
<th>名称</th>
<th>是否是集合中第一个元素</th>
<th>是否是集合中最后一个元素</th>
<th>显示当前遍历的索引</th>
<th>显示当前遍历的计数</th>
</tr>
<c:forEach items="${requestScope.list}" var="abc" varStatus="st" >
<tr id="${st.index%2==0?"even":"odd"}" >
<td>${pageScope.abc}</td>
<td>${pageScope.st.first}</td>
<td>${pageScope.st.last}</td>
<td>${pageScope.st.index}</td>
<td>${pageScope.st.count}</td>
</tr>  
</c:forEach>
 </table>
<hr>
<!-- ----------------------------------------------------------------------- -->
<c:forEach begin="1" end="100" step="1" var="num" >
${num}
</c:forEach>    
//-------------------------------------------------------
fmt库  格式化库
格式化日期
<!--  
  格式化日期
  fmt:formatDate
  -->
    <fmt:formatDate value="<%=new Date() %>"  
    pattern="yyyy/MM/dd hh:mm:ss" var="date" scope="request" />
   
    ${requestScope.date}
格式化数字
<!--  
  格式化数字
  fmt:formatNumber
  -->
    <fmt:formatNumber  value="3.1415926" pattern="0000.00000000000" var="num1" scope="request" ></fmt:formatNumber>
    <fmt:formatNumber  value="3.1415926" pattern="####.###########" var="num2" scope="request" ></fmt:formatNumber>
    ${requestScope.num1}<br>
    ${requestScope.num2}<br>
//------------------------------------------------------------------------------------
路径总结
前提: 所有路径都应以"/"开头.

项目名:day10-jsp
资源名:AServlet

客户端路径 => 给浏览器用的路径 => 填写项目名称
<form action="/day10-jsp/AServlet" >
<img src="/day10-jsp/AServlet" >
<a href="/day10-jsp/AServlet" >
response.sendRedirect("/day10-jsp/AServlet")
服务器端路径 => 给服务器端使用的路径 => 填写项目下的路径
request.getRequestDispatcher("/AServlet")
errorPage="/AServlet"
<location>/AServlet</location>
//-----------------------------------------------------------------------------------------------------------------------------
JSP发展历程(JSPModel)
JSP Model1 1代: JSP刚刚出现,想取代Servlet. 所有逻辑处理,和页面显示都在JSP中完成.
JSP Model1 2代: JSP取代Servlet,改良一代中JSP过为臃肿情况.将一部分业务逻辑分离到了业务类中.页面中的java代码使用el,动作标签,JSTL标签 替换.
JSP Model2: 重新启用Servlet技术. 由Servlet 来负责处理业务逻辑.jsp负责显示处理结果. 做到了解耦.
MVC设计思想
JavaWeb中三层架构



Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐