JSP Freemarker
模板引擎
模板引擎的目标是 数据+模板=结果
模板引擎将数据与展现有效 解耦

主流模板引擎
Java Server Page
Freemarker
Beetl
JSP与Freemarker

JSP:入门学习
\1. 概念:
* Java Server Pages: java服务器端页面
* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
* 用于简化书写!!!
\2. 原理
* JSP本质上就是一个Servlet
\3. JSP的脚本:JSP定义Java代码的方式
1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
5 指令
* 作用:用于配置JSP页面,导入资源文件
* 格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
* 分类:
1. page : 配置JSP页面的
* contentType:等同于response.setContentType()
1. 设置响应体的mime类型以及字符集
2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
* import:导包
* errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
* isErrorPage:标识当前也是是否是错误页面。
* true:是,可以使用内置对象exception
* false:否。默认值。不可以使用内置对象exception
2. include : 页面包含的。导入页面的资源文件
* <%@include file="top.jsp"%>
3. taglib : 导入资源
* <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
* prefix:前缀,自定义的
\6. 注释:
1. html注释:
:只能注释html代码片段
2. jsp注释:推荐使用
<%-- --%>:可以注释所有
\7. 内置对象
* 在jsp页面中不需要创建,直接使用的对象
* 一共有9个:
变量名 真实类型 作用
* pageContext PageContext 当前页面共享数据,还可以获取其他八个内置对象
* request HttpServletRequest 一次请求访问的多个资源(转发)
* session HttpSession 一次会话的多个请求间
* application ServletContext 所有用户间共享数据
* response HttpServletResponse 响应对象
* page Object 当前页面(Servlet)的对象 this
* out JspWriter 输出对象,数据输出到页面上
* config ServletConfig Servlet的配置对象
* exception Throwable 异常对象
JSP
JSP(Java Server Page)java服务器页面
Jsp是J2EE的功能模块,有Web服务器执行
JSP的作用就是降低动态网页的开发难度
JSP将Java代码与HTML分离,降低难度
本质是Servlet
JSP页面放在Web应用程序目录下

需要导入:D:\apache-tomcat-8.5.69\lib\jsp-api.jar
JSP代码块
JSP代码块用于在JSP文件中嵌入Java代码
JSP代码块语法:<%java代码%>
例如:<% System.out.println("hello world");%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<th>year</th>
<th>salary</th>
</tr>
<%
for(int i = 0 ; i <=50 ; i++){
out.println("<tr>");
out.println("<td>" + i +"</td>");
int sal = 0;
if(i <= 5){
sal = 1500 + i * 150;
}else if(i > 5 && i <=10){
sal = 1500 + 150 * 5 + 300 * (i-5);
}else if (i > 10){
sal = 1500 + 150 * 5 + 300 * 5 + 375 * (i-10);
}
out.println("<td>" + sal + "</td>");
out.println("</tr>");
}
%>
</table>
</body>
</html>
JSP声明代码块 (声明方法)
用于声明变量或方法
JSP声明代码块语法:<%! public int add(int a,iint b){return a+b;} %>
JSP输出指令(out.println())
在JSP页面中显示java代码执行结果
语法:<%= java代码 %>
例如:<%= ""+name+"" %>
JSP处理指令
提供JSP执行过程中的辅助信息
语法:<%@ java指令 %>
例如:<%@ page import="java.util.*" %>
JSP常用处理指令
<%@ page %> 定义当前JSP页面全局设置
<%@ include %> 将其他JSP页面与JSP页面合并
<%@ taglib %> 引入JSP标签库
JSP中注释的区别
<%--注释--%> JSP注释,别注释语句不做任何处理
// ,/../ 用于注释<% %>的代码,被注释代码不执行
HTML注释,被注释的语句不会被浏览器解释练习:质数
<%@page import="java.util.*,java.text.*" contentType="text/html;charset=utf-8" %>
<%!
boolean isPrime(int num){
boolean flag = true;
for(int j = 2 ; j < num ; j++){
if(num % j == 0){
flag = false;
break;
}
}
return flag;
}
%>
<%
List<Integer> primes = new ArrayList();
for(int i = 2 ; i<=1000 ; i++){
boolean flag = isPrime(i);
if(flag == true){
//out.println("<h1> " + i + "</h1>");
primes.add(i);
}
}
%>
<%
for(int p : primes){
//out.println("<h1>" + p + "是质数</h1>");
%>
<h1 style="color:red;"><%=p %>是质数</h1>
<%
}
%>
JSP页面重用
页眉:
新建文件夹include
<%@page contentType="text/html;charset=utf-8"%>
要闻|推荐|财经|娱乐
页脚:
<%@page contentType="text/html;charset=utf-8"%>
<hr/>
Copyright 1999-2019
正文:
<%@page contentType="text/html;charset=utf-8" %>
<%@include file="include/header.jsp" %>
<%
out.println("<h1>新闻标题</h1>");
out.println("<p>新闻正文</p>");
%>
<%@include file="include/footer.jsp" %>
把三个JSP文件合并在一个JSP文件中进行统一编译执行
JSP九大内置对象

在转义后的java文件中
源码中_jspService方法与service方法一致,有request和response参数
几大对象在源码中进行了初始化和声明
一.out输出流对象
隐藏对象out是javax.servlet.jsp.JspWriter类的实例服务器向客户输出的字符内容可以通过out对象输出。获取方法: PrintWriter out = response.getWriter();out对象常用的方法如下:
1 void clear() 清除缓冲区的内容
2 void clearBuffer() 清除缓冲区的当前内容
3 void flush() 将缓冲内容flush到客户端浏览器
4 int getBufferSize() 返回缓冲大小,单位KB
5 int getRemaining() 返回缓冲剩余大小,单位KB
6 isAutoFlush() 返回缓冲区满时,是自动清空还是抛出异常
7 void close() 关闭输出流
二.request请求对象
隐藏对象request是javax.servlet.ServletRequest类的实例,代表客户端的请求。request包含客户端的信息以及请求的信息,如请求那个文件,附带的地址参数等。每次客户端的请求都会产生一个request实例。request对象的常用方法如下:
1 object getAttribute(String name) 返回指定属性的属性值
2 Enumeration getAttributeNames() 返回所有可用属性名的枚举
3 String getCharacterEncoding() 返回字符编码方式
4 int getContentLength() 返回请求体的长度(以字节数)
5 String getContentType() 得到请求体的MIME类型
6 ServletInputStream getInputStream() 得到请求体中一行的二进制流
7 String getParameter(String name) 返回name指定参数的参数值
8 Enumeration getParameterNames() 返回可用参数名的枚举
9 String[] getparameterValues(String name) 返回包含参数name的所有值的数组
10 String getProtocol() 返回请求用的协议类型及版本号
11 String getScheme() 返回请求用的计划名,如:http https及ftp等
12 int getServerPort() 返回服务器接受此请求所用的端口号
13 String getServerName() 返回接受请求的服务器主机名
14 BufferedReader getReader() 返回解码过了的请求体
15 String getRemoteAddr() 返回发送此请求的客户端IP地址
16 String getRemoteHost() 返回发送此请求的客户端主机名
17 void setAttribute(String key Object obj) 设置属性的属性值
18 String getRealPath(String path) 返回一虚拟路径的真实路径
19 void setCharacterEncoding(“gb2312”) 设置接受参数的字符集
三.response响应对象
隐藏对象response是javax.servlet.ServletResponse类的实例,代表客户端的响应。服务器端的任何输出都通过response对象发送到客户端浏览器。每次服务器端都会响应一个response实例。response对象的常用方法如下:
1 String getCharacterEncoding() 返回响应用的是何种字符编码
2 ServletOutputStream getOutputStream() 返回响应的一个二进制输出流
3 PrintWriter getWriter() 返回可以向客户端输出字符的一个对象
4 void setContentLength(int len) 设置响应头长度
5 void setContentType(String type) 设置响应的MIME类型
6 sendRedirect(java.lang.String location) 重新定向客户端的请求
7 void setCharacterEncoding(“gb2312”) 设置响应头的字符集
四config配置对象
隐藏对象config是javax.servlet.ServletConfig类的实例,ServletConfig封装了配置在web.xml中初始化JSP的参数。JSP中通过config获取这些参数。每个JSP文件中共有一个config对象。config对象的常用方法如表:
1 String getInitParameter(String name) 返回配置在web.xml中初始化参数
2 Enumeration getInitParameterNames() 返回所有的初始化参数名称
3 ServletContext getServletContext() 返回ServletContext对象
4 String getServletName 返回Servlet对象
五.session会话对象
隐藏对象session是javax.servlet.http.HttpSession类的实例。session与cookie是记录客户访问信息的两种机制,session是用于服务器端保存用户信息,cookie用于在客户端保存用户信息。Servlet中通过request.getSession()来获取session对象,而JSP中可以直接使用。如果JSP中配置了<%@page session=”false”%>,则隐藏对象session不可用。每个用户对应一个session对象。session对象的常用方法如下:
1 long getCreationTime() 返回Session创建时间
2 public String getId() 返回Session创建时JSP引擎为它设的唯一ID号
3 long getLastAccessedTime() 返回此Session里客户端最近一次请求时间
4 int getMaxInactiveInterval() 返回两次请求间隔多长时间此Session被取消(ms)
5 String[] getValueNames() 返回一个包含此Session中所有可用属性的数组
6 void invalidate() 取消Session,使Session不可用
7 boolean isNew() 返回服务器创建的一个Session,客户端是否已经加入
8 void removeValue(String name) 删除Session中指定的属性
9 void setAttribute(String key,Object obj) 设置Session的属性
10, Object getAttribute(String name) 返回session中属性名为name的对象
六.application应用程序对象
隐藏对象application是javax.servlet.ServletContext类的对象。application封装JSP所在Web应用程序的信息,例如web.xml中国配置的全局的初始化信息。Servlet中application对象需要通过ServletConfig.getServletContext()来获取。整个Web应用程序对应一个application对象。application对象常用的方法如下:
1, Object getAttribute(String name) 返回application中属性为name的对象
2, Enumeration getAttributeNames() 返回application中的所有属性名
3, void setAttribute(String name,Object value) 设置application属性
4, void removeAttribute(String name) 移除application属性
5, String getInitParameter(String name) 返回全局初始话函数
6, Enumeration getInitParameterNames() 返回所有的全局初始话参数
7, String getMimeType(String filename) 返回文件的文档类型,例如getMimeType(“abc.html”)将返回“text.html”
8, String getRealPath(String relativePath) 返回Web应用程序内相对网址对应的绝对路径
七.page页面对象
隐藏对象page是javax.servlet.jsp.HttpJspPage类的实例。page对象代表当前JSP页面,是当前JSP编译后的Servlet类的对象。
page想当于Java类中的关键字this
八.pageContext页面上下文对象
隐藏对象pageContext为javax.servlet.jsp.PageContext类的实例。pageContext对象代表当前JSP页面编译后的内容。通过pageContext能够获取到JSP中的资源。pageContext常用方法如下:
1 JspWriter getOut() 返回out对象
2 HttpSession getSession() 返回Session对象(session)
3 Object getPage() 返回page对象
4 ServletRequest getRequest() 返回request对象
5 ServletResponse getResponse() 返回response对象
6 void setAttribute(String name,Object attribute) 设置属性及属性值 ,在page范围内有效
7 void setAttribute(String name,Object obj,int scope) 在指定范围内设置属性及属性值 ,int1=page,2=request,3=session,4=application
8 public Object getAttribute(String name) 取属性的值
9 Object getAttribute(String name,int scope) 在指定范围内取属性的值
10 public Object findAttribute(String name) 寻找一属性,返回起属性值或NULL
11 void removeAttribute(String name) 删除某属性
12 void removeAttribute(String name,int scope) 在指定范围删除某属性
13 int getAttributeScope(String name) 返回某属性的作用范围
14 Enumeration getAttributeNamesInScope(int scope) 返回指定范围内可用的属性名枚举
15 void release() 释放pageContext所占用的资源
16 void forward(String relativeUrlPath) 使当前页面重导到另一页面
17 void include(String relativeUrlPath) 在当前位置包含另一文件
九.Eexception异常对象
隐藏对象exception为java.lang.Exception类的对象。exception封装了JSP中抛出的异常信息。要使用exception隐藏对象,需要设置<%@page isErrorPage”true”%>。隐藏对象exception通常被用来处理错误页面,
JSP之三大指令
一.page指令
实例:<%@ page language=”java” import=”java.util.” pageEncoding=”UTF-8”%>
import:等同与import语句
<%@ page import=”java.util.” %>
<%@ page import=”java.util., java.net.” %>
在一个JSP页面中可以给出多个page指令,而且import是可以重复出现的
<%@ page import=”java.util.” %>
<%@ page import=”java.next.” %>
pageEncoding:指定当前页面的编码
如果pageEncoding没有指定,那么默认为contentType的值;
如果pageEncoding和contentType都没有指定,那么默认值为iso-8859-1
contentType:等同与调用response.setContentType(“text/html;charset=xxx”);
如果没有指定contentType属性,那么默认为pageEncoding的值;
如果contentType和pageEncoding都没有指定,那么默认值为iso-8859-1
errorPage:如果当前页面出现异常,那么跳转到errorPage指定的jsp页面。
例如:<%@ page errorPage=”b.jsp” %>
isErrorPage:上面示例中指定b.jsp为错误页面,但在b.jsp中不能使用内置对象exception,保有b.jsp中使用<%@page isErrorPage=”true”%>时,才能在b.jsp中使用错误页面。
autoFlush:当autoFlush为true时,表示out流缓冲区满时会自动刷新。默认为true
buffer:指定out流的缓冲区大小,默认为8KB
isELIgnored:当前JSP页面是否忽略EL表达式,默认为false,表示不忽略,即支持EL表达式
page指令不常用的属性:
language:当前JSP编译后的语言!默认为java,当前也只能选择java
info:当前JSP的说明信息
isThreadSafe:当前JSP是否执行只能单线程访问,默认为false,表示支持并发访问
session:当前页面是否可以使用session,默认为false,表示支持session的使用。
extends:指定JSP编译的servlet的父类!
二.include指令
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
Include指令的语法格式如下:
<%@ include file=”文件相对 url 地址” %>
三.taglib指令
taglib指令是用来在当前jsp页面中导入第三方的标签库
<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” % prefix=”c” >
prefix:指定标签前缀,这个东西可以随意起名
uri:指定第三方标签库的uri(唯一标识)
当然,需要先把第三方标签库所需jar包放到类路径中。
JSTL与EL表达式
EL(Expression Language)表达式语言,用于简化JSP的输出
EL表达式
\1. 概念:Expression Language 表达式语言
\2. 作用:替换和简化jsp页面中java代码的编写
\3. 语法:${表达式}
\4. 注意:
* jsp默认支持el表达式的。如果要忽略el表达式
1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
2. ${表达式} :忽略当前这个el表达式
\5. 使用:
1. 运算:
* 运算符:
1. 算数运算符: + - * /(div) %(mod)
2. 比较运算符: > < >= <= == !=
3. 逻辑运算符: &&(and) ||(or) !(not)
4. 空运算符: empty
* 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
* ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
* ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
2. 获取值
1. el表达式只能从域对象中获取值
2. 语法:
1. ${域名称.键名}:从指定域中获取指定键的值
* 域名称:
1. pageScope --> pageContext
2. requestScope --> request
3. sessionScope --> session
4. applicationScope --> application(ServletContext)
* 举例:在request域中存储了name=张三
* 获取:${requestScope.name}
2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
3. 获取对象、List集合、Map集合的值
1. 对象:${域名称.键名.属性名}
* 本质上会去调用对象的getter方法
2. List集合:${域名称.键名[索引]}
3. Map集合:
* ${域名称.键名.key名称}
* ${域名称.键名["key名称"]}
3. 隐式对象:
* el表达式中有11个隐式对象
* pageContext:
* 获取jsp其他八个内置对象
* ${pageContext.request.contextPath}:动态获取虚拟目录
1.EL表达式的基本语法:${表达式}
例:
学生姓名:${student.name}
作用域对象
| 作用域对象 | 描述 |
|---|---|
| pageScope | 从当前页面获取值 |
| requestScope | 从当前请求获取属性值 |
| sessionScope | 从当前回话中获取属性值 |
| applocationScope | 从当前应用获取全局属性值 |
2.EL输出参数值
EL表达式内置param对象来简化参数的输出request.getParameter();
语法:${param.参数名}
package com.imooc.el;
public class Student {
private String name;
private String mobile;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String toString() {
return name + ":" + mobile;
}
}
package com.imooc.el;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/info")
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public StudentServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String teacher = request.getParameter("teacher");
Student stu = new Student();
stu.setName("子墨");
stu.setMobile(null);
String grade = "A";
// request.setAttribute("grade", "B");
// request.getServletContext().setAttribute("grade", "C");
HttpSession session = request.getSession();
session.setAttribute("student", stu);
session.setAttribute("grade", grade);
List list = new ArrayList();
list.add("A");
list.add("B");
list.add("C");
session.setAttribute("list",list);
// request.setAttribute("student", stu);
// request.setAttribute("grade", grade);
request.getRequestDispatcher("/el_info.jsp").forward(request, response);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>姓名:${sessionScope.student.name }</h1>
<h2>手机:${sessionScope.student.mobile }</h2>
<h2>讲师:${param.teacher }</h2>
<h2>评级:${sessionScope.grade }</h2>
<h2>概要:${student }</h2>
<c:forEach items="${list }" var="l">
${l}
</c:forEach>
</body>
</html>
JSTL标签库
JSTL(JSP Standard Tag Library) jsp标椎标签库
\1. 概念:JavaServer Pages Tag Library JSP标准标签库
* 是由Apache组织提供的开源的免费的jsp标签 <标签>
\2. 作用:用于简化和替换jsp页面上的java代码
\3. 使用步骤:
1. 导入jstl相关jar包
2. 引入标签库:taglib指令: <%@ taglib %>
3. 使用标签
\4. 常用的JSTL标签
1. if:相当于java代码的if语句
1. 属性:
* test 必须属性,接受boolean表达式
* 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
* 一般情况下,test属性值会结合el表达式一起使用
2. 注意:
* c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签
2. choose:相当于java代码的switch语句
1. 使用choose标签声明 相当于switch声明
2. 使用when标签做判断 相当于case
3. 使用otherwise标签做其他情况的声明 相当于default
3. foreach:相当于java代码的for语句
简化JSP
由SUN(oracle)定义规范,由Apache Tomcat 团队实现
需要导入:包,并且把包放入tomcat的lib文件夹下
| 包 | 描述 |
|---|---|
| taglibs-standard-spec-1.2.5.jar | 标签库定义包(必须) |
| taglibs-standard-impl-1.2.5.jar | 标签库实现包(必须) |
| taglibs-standard-jstlel-1.2.5.jar | el表达式支持包(备选) |
| taglibs-standard-compat-1.2.5.jar | 1.0版本兼容包(备选) |
JSTL的标签库种类
| 类别 |
|---|
| 核心标签库--core |
| 格式化输出标签库--fmt |
| SQL操作标签库--sql |
| XML操作标签库--xml |
| 函数标签库--functions |
引入
在JSP文件第二行加入<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>在taglibs-standard-impl-1.2.5.jar/META_INF/c.tld文件中,定义了所有标签
判断标签
1.<c:if> 单分支判断
2.<c:choose>.<c:when>.<c:otherwise> 多分支判断
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!-- 在Java或者JSP文件中输入 Alt + / 可出现智能提示 --><%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body> <h1>${requestScope.score}</h1> <c:if test = "${score >= 60 }"> <h1 style = "color:green">恭喜,你已通过测试</h1> </c:if> <c:if test = "${score < 60 }"> <h1 style = "color:red">对不起,再接再厉</h1> </c:if> <!-- choose when otherwise --> ${grade } <c:choose> <c:when test="${grade == 'A'}"> <h2>你很优秀</h2> </c:when> <c:when test="${grade == 'B' }"> <h2>不错呦</h2> </c:when> <c:when test="${grade == 'C' }"> <h2>水平一般,需要提高</h2> </c:when> <c:when test = "${grade == 'D'}"> <h2>需要努力啦,不要气馁</h2> </c:when> <c:otherwise> <h2>一切随缘吧</h2> </c:otherwise> </c:choose> <!-- forEach标签用于遍历集合 List companys = (List)request.getAttribute("companys") for(Company c : companys){ out.print("...") } idx = index idx.index属性代表循环的索引值(0开始) --> <c:forEach varStatus="idx" items = "${requestScope.companys }" var = "c"> <h2>${idx.index + 1}-${c.cname }-${c.url }</h2> </c:forEach> </body></html>
遍历集合
<c:forEach>标签用于集合(Collection)中的每一个对象<c:forEach var="p" items="${persons}" varStatus="idx" > 第 ${idx.index+1} 位 <br/> 姓名:${p.name} 性别:${p.sex}年龄:${p.age}</c:forEach>
fmt格式化标签库
fmt格式化标签库 URI:http://java.sun.com/jsp/jstl/fmt<fmt:formatDate value = "" pattern = "" /> 格式化日期标签<fmt:formatNumber value = "" pattern = ""/> 格式化数字标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body> <% request.setAttribute("amt", 1987654.326); request.setAttribute("now", new java.util.Date()); request.setAttribute("html", "<a href='index.html'>index</a>"); request.setAttribute("nothing", null); %> <h2>${now }</h2> <!-- formatDate pattern yyyy - 四位年 MM - 两位月 dd - 两位日 HH - 24小时制 hh - 12小时制 mm - 分钟 ss - 秒数 SSS - 毫秒 --> <h2> <fmt:formatDate value="${requestScope.now }" pattern="yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒" /> </h2> <h2>${amt }</h2> <h2>¥<fmt:formatNumber value = "${amt }" pattern="0,00.00"></fmt:formatNumber>元</h2> 输出设置默认值 <h2>null默认值:<c:out value="${nothing }" default="无"></c:out> </h2> 特殊字符转义,可输出原有文本 <h2><c:out value="${ html}" escapeXml="true"></c:out></h2></body></html>
Freemarker
FreeMarker是免费开源的模板引擎技术
Freemarker脚本为FreeMarker Template Language
Freemarker提供了大量内建函数来简化开发
官网 https://freemarker.apache.org/
中文参考手册 http://freemarker.foofun.cn/
FreemakerSample1 类package com.imooc.ferrmarker;import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateException;import java.io.IOException;import java.io.OutputStreamWriter;import java.util.HashMap;import java.util.Map;public class FreemakerSample1 { public static void main(String[] args) throws IOException, TemplateException { //1.加载模板 Configuration configuration=new Configuration(Configuration.VERSION_2_3_0); configuration.setClassForTemplateLoading(FreemakerSample1.class,""); Template t=configuration.getTemplate("sample.ftl"); //2.加载数据 Map<String,Object> data=new HashMap<String, Object>(); data.put("site","百度"); data.put("url","http://www.baidu.com"); //3.产生输出 t.process(data,new OutputStreamWriter(System.out)); }}
sample.ftl
${site}-${url}
FTL取值
| $ | 取值 可对属性进行计算 |
|---|---|
| $ | 使用默认值 |
| $ | 格式化输出 |
View Code
package com.imooc.ferrmarker;import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateException;import java.io.IOException;import java.io.OutputStreamWriter;import java.util.Date;import java.util.HashMap;import java.util.Map;public class FreemakerSample1 { public static void main(String[] args) throws IOException, TemplateException { //1.加载模板 Configuration configuration=new Configuration(Configuration.VERSION_2_3_0); configuration.setClassForTemplateLoading(FreemakerSample1.class,""); Template t=configuration.getTemplate("sample.ftl"); //2.加载数据 Map<String,Object> data=new HashMap<String, Object>(); data.put("site","百度"); data.put("url","http://www.baidu.com"); Date date=new Date(); data.put("date",date); data.put("number",864464.165); Map info=new HashMap(); info.put("cpu","i7-8500"); info.put("rom","2T"); Computer c=new Computer("1234","LEGION",1,"小四",new Date(),129f,info); data.put("computer",c); //3.产生输出 t.process(data,new OutputStreamWriter(System.out)); }}
${site}-${url}${att!'不存在的属性'}${date?string("yyyy-MM-dd-mm-ss SSS")}${number?string("0.00")} <#--默认货币-->SN:${computer.sn}model:${computer.model}state:${computer.state}user:${computer.user}dop:${computer.dop?string("yyyy-MM-dd")}price:${computer.price?string("0.00")}配置:CPU:${computer.info["cpu"]}内存:${computer.info["rom"]}
if分支
<#if 条件1>条件1 成立执行代码<#elseif 条件2>条件2 成立执行代码<#elseif 条件3>条件3 成立执行代码<#else>其他情况下执行代码
<#if computer.sn=="sdad"> <#-- 判断字符直接用 == --> 重要设备</#if>model:${computer.model}<#if computer.state==1> 状态:正在使用<#elseif computer.state==2> 状态:闲置<#elseif computer.state==3> 状态:报废了</#if>state:${computer.state}<#if computer.state??> <#-- ??判断是否位空--> user:${computer.user}</#if>
switch分支判断
<#switch value> <#case refValue1> ... <#break> <#case refValue2> ... <#break> <#case refValueN> ... <#break> <#default> ...</#switch>
<#switch computer.state> <#case 1> 状态:正在使用 <#break > <#case 2> 状态:闲置 <#break > <#case 3> 状态:报废了 <#break > <#default > 状态:无效</#switch>
list迭代列表
<#list students as stu> <li>${stu_index }-${stu.name}</li></#list>
list迭代Map
<#list map?keys as key> ${key}:${map[key]}</#list>
View Code
<#list computers as c>序号:${c_index + 1} <#-- 迭代变量_index保存了循环的索引,从0开始 -->SN:${c.sn}型号:${c.model}<#switch c.state><#case 1>状态:使用中<#break><#case 2>状态:闲置<#break><#case 3>状态:已作废<#break></#switch><#if c.user??>用户:${c.user}</#if>采购日期:${c.dop?string("yyyy-MM-dd")}采购价格:${c.price?string("0.00")}-------------------------------------------</#list>==========================================<#list computer_map?keys as k >${k}-${computer_map[k].model}${computer_map[k].price?string("0.00")}</#list>
list数字序列迭代
<#list 1..20 as x> <li>${x}</li></#list>
内建函数
| 函数名 | 说明 | 示例 |
|---|---|---|
| substring | 截取字符串 | "abcdefg"?substring(2,4) |
| cap_first | 首字母大写 | "jackson"?cap_first |
| index_of | 查找字符索引 | "abcdef"?index_of("b") |
| length | 返回字符串长度 | "abcdef"?length |
| round/floor/ceiling | 四舍五入 下取整 上取整 | pi?floor |
| size | 得到集合元素总数 | students?size |
| first/last | 获取第一个 最后一个元素 | student?first |
| sort_by | 按某个属性对集合排序 | list?sort_by("time") |
View Code
${name?cap_first}${brand?upper_case}${brand?length}${words?replace("blood" , "*****")}${words?index_of("blood")}<#-- 利用?string实现三目运算符的操作 -->${(words?index_of("blood") != -1)?string("包含敏感词汇","不包含敏感词汇")}${n?round}${n?floor}${n?ceiling}公司共有${computers?size}台电脑第一台:${computers?first.model}最后一台:${computers?last.model}<#list computers?sort_by("price")?reverse as c> ${c.sn}-${c.price}</#list>
MVC模式
MVC:开发模式
\1. jsp演变历史
1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
2. 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难于维护,难于分工协作
3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性
\2. MVC:
1. M:Model,模型。JavaBean
* 完成具体的业务操作,如:查询数据库,封装对象
2. V:View,视图。JSP
* 展示数据
3. C:Controller,控制器。Servlet
* 获取用户的输入
* 调用模型
* 将数据交给视图进行展示
* 优缺点:
\1. 优点:
1. 耦合性低,方便维护,可以利于分工协作
2. 重用性高
\2. 缺点:
1. 使得项目架构变得复杂,对开发人员要求高

以前显示与代码耦合
URL: http://localhost:8080/square.jsp?max=100-----------------------------------------------------<ul><% int max = Integer.parseInt(request.getParameter("max")); for(int i = 0 ; i <= max ; i++){ long result = i * i; out.print("<li>"); out.print(i + "的平方是" + result); out.print("</li>"); }%></ul>

Model - 模型
模型(Model)负责生产业务需要的数据
public class MathService{ public List square(int max){ List list = new ArrayList(); for(int i = 0 ; i <= max ; i++){ long result = i * i; list.add(result); } return list; }}
Controller - 控制器
控制器(Controller)是界面(View)与模型(Model)粘合剂
@WebServlet("/square")public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest req,HttpServletResponse res){ //1. 接收数据 int max = Integer.parseInt(request.getParameter("max")); //2. 调用处理类(模型)进行处理 MathService ms = new MathService(); List list = ms.square(max); req.setAttribute("squareList",list); //3. 跳转界面(View) request.getRequestDispatcher("/result.jsp").forward(req,res); }}
View - 视图
视图(View)用于展示最终结果
URL: http://localhost:8080/square?max=100------------------------------------------------<ul><c:foreach items="${squareList}" var="r" varStatus="idx"> <li>${idx.index}的平方是${r}</li></c:foreach></ul>
MVC架构模式优点
软件团队分工合作,成员各司其职
分层开发,显示与数据解耦,便于维护
组件可灵活替代,互不影响
工程结构

包结构

Data Access Object
XxxDao类只负责对数据进行读取、写入操作

Service与Dao的关系
Service负责进行流程处理,需持久化时调用
Dao只负责单纯对数据进行查询、写入操作
Service允许单向调用Dao,反向则不允许
MVC调用关系

JavaBean
JavaBean是一种Java中可重用组件
JavaBean不是技术,而是一种Java类的格式要求
u JavaBean在Java领域非常常见,通常用于存储数据
JavaBean格式要求
- 类必须是public并提供默认构造函数
- 所有属性private私有化
- 属性通过getter与setter方法进行读写
public class Painting { //类公有化
public Painting(){...}; //提供默认构造函数,可不写
private Integer id; //属性私有
private String pname;
public Integer getId() {return id;} //getter获取属性值
public void setId(Integer id) {this.id = id;} //setter设置属性值
public String getPname() {return pname;}
public void setPname(String pname) {this.pname = pname;}
}

三层架构:软件设计架构
\1. 界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互
\2. 业务逻辑层:处理业务逻辑的。
\3. 数据访问层:操作数据存储文件。


浙公网安备 33010602011771号