JSP
java server pages java 服务端页面
jsp = java + html
为什么用JSP?
JSP 为动态页面而生,当页面需要展示动态的数据时,我们不可能像下图这样用 servlet 中的 write 写整个页面。那样太过繁琐和复杂。
JSP 的作用:简化开发,避免用 Servlet 输出 HTML 标签。
JSP 原理
JSP 本质上就是 Servlet
JSP在被访问时,由JSP容器(Tomcat)将其转换为Java文件(Servlet),再由JSP容器(Tomcat)将其编译,最终对外提供服务的其实就是这个字节码文件
JSP 脚本
<% %>
- 在 _JspService() 方法中使用
<%= %>
- 等价于
<% out.print() %>
<%! %>
- 在 _JspService() 之外,直接被类包含,就是成员位置
举例
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1>Hello Html!</h1>
<%!
String username = "zhangsan";
void showName() {
System.out.println(username);
}
%>
<%
String str = "Hello Jsp~";
out.print(str + "<br>");
System.out.println(str);
showName();
%>
<%="Hello out.print()" + str%>
</body>
</html>
生成的hello_jsp.java
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
// 在 <%! %> 中编辑的内容作为成员变量
String username = "zhangsan";
void showName() {
System.out.println(username);
}
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>Hello</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<h1>Hello Html!</h1>\r\n");
out.write("\r\n");
out.write("\r\n");
String str = "Hello Jsp~";
out.print(str + "<br>");
System.out.println(str);
showName();
out.write("\r\n");
out.write("\r\n");
out.print("Hello out.print()" + str);
out.write("\r\n");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
JSP 查询数据库并展示
<%@ page import="java.util.List" %>
<%@ page import="com.jsp.pojo.Hero" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="org.apache.ibatis.io.Resources" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactory" %>
<%@ page import="org.apache.ibatis.session.SqlSessionFactoryBuilder" %>
<%@ page import="org.apache.ibatis.session.SqlSession" %>
<%@ page import="com.jsp.mapper.HeroMapper" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
HeroMapper heroMapper = sqlSession.getMapper(HeroMapper.class);
List<Hero> heroList = heroMapper.selectAll();
sqlSession.close();
%>
<html>
<head>
<title>Hero</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap-theme.min.css" integrity="sha384-6pzBo3FDv/PJ8r2KRkGHifhEocL+1X2rVCTTkUfGk7/0pbek5mMa1upzvWbrUbOZ" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
</head>
<body>
<div class="panel panel-default col-lg-4">
<!-- Default panel contents -->
<div class="panel-heading">英雄列表</div>
<!-- Table -->
<table class="table">
<tr>
<th>ID</th>
<th>英雄</th>
<th>生命</th>
<th>伤害</th>
</tr>
<%
for (Hero hero : heroList) {
int id = hero.getId();
String name = hero.getName();
int hp = hero.getHp();
float damage = hero.getDamage();
%>
<tr>
<td><%=id%></td>
<td><%=name%></td>
<td><%=hp%></td>
<td><%=damage%></td>
</tr>
<%
}
%>
</table>
</div>
</body>
</html>
效果展示
JSP 脚本可以被截断
如下,将 for 循环截断,包含一段 <tr>
元素,这样会在页面自动遍历展示列表。
<%
for (Hero hero : heroList) {
int id = hero.getId();
String name = hero.getName();
int hp = hero.getHp();
float damage = hero.getDamage();
%>
<tr>
<td><%=id%></td>
<td><%=name%></td>
<td><%=hp%></td>
<td><%=damage%></td>
</tr>
<%
}
%>
JSP 的缺点
由于JSP页面内,既可以定义HTML标签,又可以定义Java代码,造成了以下问题:
- 书写麻烦:特别是复杂的页面
- 阅读麻烦
- 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE...
- 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
- 调试困难:出错后,需要找到自动生成的.java文件进行调试
- 不利于团队协作:前端人员不会Java,后端人员不精HTML 心
替代品:HTML + AJAX
综上,可见单独使用 JSP 技术会使页面臃肿不堪,难以阅读维护,无法分工合作。所以,应该采取 Servlet + JSP 的方式,尽量地让 Servlet 只做业务逻辑,让 JSP 只做数据展示。
所以,就需要 EL 表达式、JSTL 标签这两个技术。
EL 表达式
- Expression Language表达式语言,用于简化JSP页面内的Java代码
- 功能:获取数据
- 语法:
${expression}
${username}
:获取域中存储的 key 为username的数据值
JavaWeb 四大域对象:
域对象 | 生效位置 |
---|---|
page | 当前页面 |
request | 当前请求 |
session | 当前会话 |
application | 当前应用 |
EL 表达式会从内向外寻找,直到找到数据为止。
JSTL 标签
依赖
<!--JSTL标签库-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
if 标签
<c:if test="${heroDamage > 500}">
<h1>${heroName}伤害很高</h1>
</c:if>
for-each 标签
<c:forEach items="${heroList}" var="hero" varStatus="status">
<tr>
<%--<td>${hero.id}</td>--%>
<td>${status.count}</td>
<td>${hero.name}</td>
<td>${hero.hp}</td>
<td>${hero.damage}</td>
<td>
<c:if test="${hero.damage <= 800}">
战士
</c:if>
<c:if test="${hero.damage > 800}">
刺客
</c:if>
</td>
</tr>
</c:forEach>
varStatus 是遍历状态信息,有两个子项
- index 从 0 开始
- count 从 1 开始
普通 for 循环
<div>
<c:forEach begin="0" end="10" step="1" var="num">
<a href="#">${num}</a>
</c:forEach>
</div>
效果:
分页条的原型。
标签:笔记,write,JSP,jsp,servlet,javax,out From: https://www.cnblogs.com/libayu/p/17278223.html