jsp中的动态网页实现[
servlet实现动态页面
Servlet同样也可以向浏览器动态响应HTML,但是需要大量的字符串拼接处理,在JAVA代码上大量拼接HTML字符串是非常繁琐耗时的一件事,它涉及到HTML本身的字符串处理,还涉及到css样式代码和文件,以及js脚本代码和文件,HTML中的各种外部引入路径等等,处理起来相当的麻烦
<%--
Created by IntelliJ IDEA.
User: Gavin
Date: 2021/10/19
Time: 8:53
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<style>
table{border: 1px solid green;width: 50%;margin: 0px auto;}
table td{border: 1px solid blue;}
</style>
</head>
<body>
<%
int h=Integer.parseInt(request.getParameter("height"));
int r= Integer.parseInt(request.getParameter("row"));
StringBuilder sbd= new StringBuilder();
sbd.append("<table>");
for (int i = 0; i < h; i++) {
sbd.append("<tr>");
for (int j = 0; j < r; j++) {
sbd.append("<td>");
sbd.append(String.valueOf(i));
sbd.append(String.valueOf(j));
sbd.append("</td>");
}
sbd.append("</tr>");
}
sbd.append("</table>");
out.print(sbd);
%>
</body>
</html>
jsp实现动态网页
简单理解就是在html的基础上扩展 了,在jsp中可以插入java代码了;
java代码插入的形式----
<% java代码 %>
<%@ page import="java.util.Random" %><%--
Created by IntelliJ IDEA.
User: Gavin
Date: 2021/10/19
Time: 9:30
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>test</title>
</head>
<body>
<%
Random random= new Random();
int num= random.nextInt(100);
int grade=num/10;
switch(grade){
case 10:
out.print("A+");
break;
case 9:
out.print("A");
break;
case 8:
out.print("B+");
break;
case 7:
out.print("B");
break;
case 6:
out.print("C");
break;
default:
out.print("C-");
}
%>
<%out.print(num);%>
</body>
</html>
简写形式----->>
<%@ page import="java.io.PrintWriter" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
ctrl +shift + /
JSP中通过<%%>来穿插JAVA代码
<%=变量/值%>将变量/值打印到页面上的标签显示的位置
--%>
<%
int score =(int)(Math.random()*101);
%>
分数:
<%--
<%
//PrintWriter out = response.getWriter();
out.print(score);
%>
--%>
<%=score%>
<br/>
等级:
<%
int grade =score/10;
switch (grade){
case 10:
case 9:
%>
<%="A"%>
<%
break;
case 8:
%>
<%="B"%>
<%
break;
case 7:
%>
<%="C"%>
<%
break;
case 6:
%>
<%="D"%>
<%
break;
default:
%>
<%="E"%>
<%
}
%>
</body>
</html>
jsp的运行原理是什么?
> JSP的运行原理
JSP看似是HTML代码,看似是页面,但是事实上是一种后台技术,当我们第一发送请求一个JSP资源时,JSP加载引擎会帮助我们将一个.JSP文件转换成一个.java文件,相当于自动的给我们生成了一个Servlet并将页面上HTML代码编入到这个Servlet中,然后运行这个Servlet,将数据响应给浏览器.JSP的本质其实就是一个Servlet,.JSP中的HTML代码相当于是我们向浏览器响应的HTML内容的模板
以下是Jsp经过转换后生成的java文件;
打开看一下里面有些啥---->>>
package org.apache.jsp;//包名
//test.jsp转换之后生成的java类名 test_jsp
//继承了HttpJspBase,实现了JspSourceDependent和JspSourceImports
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
来看一下HttpJspBase里都有些什么
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import org.apache.jasper.Constants;
import org.apache.jasper.compiler.Localizer;
// HttpJspBase是一个抽象类,继承了HttpServlet 实现了HttpJspPage
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
所以JSP可以看作是一个servlet,这也就不难理解在JSP网页中可以直接使用request和response对象了;
简单分析一下转译过程----->>>
jsp的整个运行过程---->>>
web.xml中
在tomcat初始化时就会加载jsp引擎,通过下面这个配置来完成jsp转换为java代码的
请求JSP是都会被JSP加载引擎所匹配,
JSP执行过程
JSP的执行过程大致可以分为两个时期:转译时期和请求时期
转译时期(Translation Time):
JSP网页转译成Servlet,生成.java文件,然后进行编译生成.class字节码文件
正好在写代码时漏了一个;,于是访问时 报错5000
请求时期(Request Time):
运行.class字节码文件,处理请求。
具体过程
1、客户端发出Request请求
2、JSP Container 将JSP转译成Servlet的源代码.java文件
3、将产生的Servlet源代码经过编译后.生成字节码.class文件
4、将.class字节码文件加载进入内存并执行,其实就是在运行一个Servlet
5、通过Response对象将数据响应给浏览器
当JSP网页在执行时,JSP Container 会做检查工作,如果发现JSP网页有更新修改时,JSP Container 才会再次编译JSP成 Servlet; 如果JSP没有更新时,就直接执行前面所产生的Servlet.**,也就是说,当我们在JSP上修改了代码时,不需要频繁的更新和重启项目,直接访问就可以完成更新
JSP的性能问题
有人都会认为JSP的执行性能会和Servlet相差很多,其实执行性能上的差别只在第一次的执行。因为JSP在执行第一次后,会被编译成Servlet的类文件,即.class,当再重复调用执行时,就直接执行第一次所产生的Servlet,而不再重新把JSP编译成Servelt。除了第一次的编译会花较久的时间之外,之后JSP和同等功能的Servlet的执行速度就几乎相同了。
JSP慢的原因不仅仅是第一次请求需要进行转译和编译,而是因为JSP作为一种动态资源,本质上就是Servlet,它是需要运行代码才会生成资源,和HTML本身资源已经存在,直接返回,有着本质上的差异,另外,JSP转译之后,内部通过大量IO流形式发送页面内容,IO流本身是一种重量级操作,是比较消耗资源的
jsp中的变量声明问题
jsp实际也就相当于一个servlet,servlet中最好不要声明全局变量,以防高并发时对数据的修改而产生不可描述的错误;
在jsp中声明 变量
两种方式有什么不同呢?
看一下转译后的java文件
在jsp中注释
jsp中有html的结构 所以可有 css注释,js注释html注释
同时由于jsp中可以穿插Java代码,所以还可以有java注释
访问javatest.jsp,查看网页编码----
会发现js,css,html注释都被发送给浏览器了,实际上是不应该被看到的;
什么原因呢?
查看java文件可以看到,js,css,html,java这四种注释都会进入java文件,然后前三种被java文件发送给浏览器了,
jsp注释没有进入到java文件;
- 1JSP注释 仅仅存在于JSP页面 不会被编入java代码 不会响应给浏览器
- html注释 不仅仅存在于JSP页面 编入java代码 会响应给浏览器
- java注释 不仅仅存在于JSP页面 编入java代码 不会响应给浏览器
- css js注释 不仅仅存在于JSP 编入java代码 会响应给浏览器
推荐在JSP 页面使用JSP注释 尤其是在注释 html代码的时候
jsp中的指令标签
指令标签是JSP页面上的一种特殊标签,JSP指令可以用来设置整个JSP页面相关的属性,如网页的编码方式,脚本语言,导包等等。
指令标签的语法
<%@ directive attribute=“value” %>
page标签---->>>>
常用的page标签—>>>
<%--全局设置--%>
<%-- page contentType 相当于 response.setContentType("text/html;charset=UTF-8")--%>
<%@ page contentType="text/html;charset=UTF-8" %>
<%--默认是java语言--%>
<%@page language="java" %>
<%--引入其他类--%>
<%@ page import="java.math.BigInteger"%>
<%--指名class文件编译编码格式,默认为content-type里一样--%>
<%@ page pageEncoding="UTF-8"%>
<%--指定错误页 当jsp中出现错误,则会跳往此页面--%>
<%@page errorPage="errortest.jsp" %>
<html>
<head>
<title>Title</title>
<script>
/* 这是js注释*/
</script>
<style type="text/css">
/*这是css注释*/
</style>
</head>
<%--这是jsp注释--%>
<body>
<!--这是html注释-->
<%
int i=100;
int result =i/0;
/*这是java注释*/%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%-- 这里设置为true表明这是一个错误页,在本页面中就可以--%>
<%@page isErrorPage="true" %>
</head>
<body>
this is an error page!<br>
<%=exception.getMessage()%>
</body>
</html>
页面并没有发生跳转而是直接响应了错误页的信息.
配置错误页----404
方式一:
<%@ page contentType="text/html;charset=UTF-8" %>
<%--指名class文件编译编码格式,默认为content-type里一样--%>
<%@ page pageEncoding="UTF-8"%>
<%--指定错误页 当jsp中出现错误,则会跳往此页面--%>
<%@page errorPage="errortest.jsp" %>
<html>
<head>
<title>Title</title>
<script>
/* 这是js注释*/
</script>
<style type="text/css">
/*这是css注释*/
</style>
</head>
<%--这是jsp注释--%>
<body>
<!--这是html注释-->
<%
int i=100;
/*手动造一个异常*/
int result =i/0;
/*这是java注释*/%>
</body>
</html>
方式二
在web.xml中配置信息当发生对应的错误码时会跳到相应的页面上去
两种方式的区别,
在页面文件中配置,只是当前页面出现了问题会跳转到对相应页面,
在web.xml中配置则是针对于全局项目中的错误都会跳转到该错误页中;
两种方式的优先级是页面配置中的优先级高于全局;
include标签
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。除了include指令标签可以实现引入以外,使用 jsp:include 也可以实现引入
静态引入----
静态引入: @include 被引入的网页和当前页生成代码后形成了一个java文件
动态引入: jsp:include 被引入的JSP页面会生成独立的java代码
taglib 标签
作用是引入jstl标签库,用于简化代码量
JSTL(Java server pages standarded tag library,即JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。
使用JSTL的好处:
开发人员可以利用JSTL和EL来开发Web程序,取代传统直接在页面上嵌入Java程序的做法,以提高程序的阅读性、维护性和方便性。在jstl中, 提供了多套标签库, 用于方便在jsp中完成或简化相关操作.
JSTL标签库的组成部分
核心标签库: core, 简称c
格式化标签库: format, 简称fmt
函数标签库: function, 简称fn
JSTL的使用前提
1需要在项目中导入jstl-1.2.jar ,jstl在后台由java代码编写, jsp页面中通过标签进行使用, 使用标签时, 会自动调用后台的java方法,
2标签和方法之间的映射关系在对应的tld文件中描述. 需要在页面中通过taglib指令引入对应的标签库, uri可以在对应的tld文件中找到
书写格式----
<%@ taglib uri=“标签库的定位” prefix=“前缀(简称)” %>
c:set c:remove c:out
代码展示—>>>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--使用核心标签库--%><%--compat 包--%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<%
request.setAttribute("msg","requestMessage");
%>
c:set
scope指定数据的域 page request session application
value 实际数据
</hr>
<br/>
<c:set scope="page" var ="msg" value="pageMessage"></c:set><br/>
<c:set scope="request" var ="msg" value="requestMessage"></c:set><br/>
<c:set scope="session" var ="msg" value="sessionMessage"></c:set><br/>
<c:set scope="application" var ="msg" value="applicationMessage"></c:set><br/>
<hr/>
四大域中的信息<br/>
page: ${pageScope.msg}<br/>
request:${requestScope.msg}<br/>
session:${sessionScope.msg}<br/>
application:${applicationScope.msg}<br/>
<br/>
<c:set scope="page" var ="msg" value="pageMessage"></c:set><br/>
<c:set scope="request" var ="msg" value="requestMessage"></c:set><br/>
<c:set scope="session" var ="msg" value="sessionMessage"></c:set><br/>
<c:set scope="application" var ="msg" value="applicationMessage"></c:set><br/>
<hr/>
<%--移除指定域中的值--%>
<c:remove var="msg" scope="page"></c:remove><br/>
<c:remove var="msg" scope="request"></c:remove><br/>
<c:remove var="msg" scope="session"></c:remove><br/>
<c:remove var="msg" scope="application"></c:remove><br/>
移除后四大域中的信息
page: ${pageScope.msg}<br/>
request:${requestScope.msg}<br/>
session:${sessionScope.msg}<br/>
application:${applicationScope.msg}<br/>
通过c:out标签获取域中的值
取出值是还是得依靠EL表达式,如果表达式为null,则就用默认值展示
<c:set scope="page" var ="msg" value="pageMessage"></c:set><br/>
<c:out value="${pageScope.msg}" default="page msg not found"/>
<c:out value="${requestScope.msg}" default="request msg not found"/>
<c:out value="${sessionScope.msg}" default="session msg not found"/>
<c:out value="${applicationScope.msg}" default="applaication msg not found"/>
</body>
</html>
c:if c:choose
<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
<head>
<title>Title</title>
</head>
<hr>
<% int num = new Random().nextInt(101);
pageContext.setAttribute("num", num);
%>
<%--<c:if test="用于放判断条件(EL表达式)" var="数据名" scope="指定域"></c:if>--%>
<%--<c:if 结构中每一个条件都要判断--%>
${num}:</br>
等级--
<c:if test="${num ge 90}" scope="page" var="f1">A</c:if>
<c:if test="${num ge 80 &&num lt 90} " scope="page" var="f2">B</c:if>
<c:if test="${num ge 70 && num lt 80}">C</c:if>
<c:if test="${num lt 70}">D</c:if>
${f1}</br>
${pageScope.f2}</br>
<c:if test="${num ge 60}" scope="page" var="flag">及格</c:if>
<c:if test="${!pageScope.flag}">不及格</c:if>
</hr></br>
<%--<c:choose>结构当判断第一个成立时,以后的就不会判断,以此类推--%>
<c:choose>
<c:when test="${num ge 90}">A</c:when>
<c:when test="${num ge 80}">B</c:when>
<c:when test="${num ge 70}">C</c:when>
<c:when test="${num ge 60}">D</c:when>
<%-- <c:when test="${num lt 60}">E</c:when>--%>
<%--其他情况--%>
<c:otherwise>E--</c:otherwise>
</c:choose>
</body>
</html>
c:foreach打印九九乘法表
打印九九乘法表<br>
<c:forEach var="i" begin="1" end="9" step="1">
<c:forEach var="j" begin="1" end="${i}" step="1">
<c:set var="x" value="${i*j}" scope="page"></c:set>
${j} * ${i}=<c:if test="${x lt 10}" var="ji" scope="page"> 0${i*j}</c:if>
<c:if test="${!ji}">${i*j}</c:if>
 
</c:forEach>
</br>
</c:forEach>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
<head>
<title>欢迎使用图书管理系统</title>
<style type="text/css">
table {
border: 4px solid black;
width:70%;
margin: 0px auto;
mso-cellspacing: 0px;
}
td,th {
border: 2px solid black;
}
</style>
</head>
<body>
<div>
<table cellpadding="0px" cellspacing="0px">
<tr>
<th>BookId</th>
<th>BookName</th>
<th>BookPublish</th>
<th>BookPrice</th>
<th>BookKind</th>
</tr>
<%--<c:forEach 中items 表示要遍历的结合或者数组---要从域中取出 var 表示 每次迭代的变量名--%>
<c:forEach items="${BookInfo}" var="book">
<tr>
<%--这里跟添加到list中的属性字段一致--%>
<td>${book.bookId} </td>
<td>${book.bookName}</td>
<td>${book.bookPublish}</td>
<td>${book.bookPrice}</td>
<td>${book.bookKind}</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>