JSP从零教学详细教程

405 阅读6分钟

JSP

JSP 基本介绍

1. JSP 全称是 Java Server Pages,Java 的服务器页面

2. JSP 这门技术的最大的特点在于,写 JSP 就像在写 HTML

● 相比 html 而言,html 只能为用户提供静态数据,而 JSP 技术允许在页面中嵌套 java 代码,为用户提供动态数据

● 相比 Servlet 而言,Servlet 很难对数据进行排版,而 jsp 除了可以用 java 代码产 生动态数据的同时,也很容易对数据进行排版。

3. jsp 技术基于 Servlet, 你可以理解成 JSP 就是对 Servlet 的包装. 4. 会使用 JSP 的程序员, 再使用 thymeleaf 是非常容易的事情, 几乎是无缝接

应用实例-JSP 基本使用

创建 javaWEB 项目,并引  jar

 

sum.jsp

<%@ page import="java.io.PrintWriter" %>
<%@ page import="org.apache.jasper.runtime.HttpJspBase" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp的简单的求和计算器</title>
</head>
<body>
<h1>jsp的简单的求和计算器</h1>
<%
    //1. 在jsp的 该标签中, 可以写java代码
    int i = 10;
    int j = 20;
    int res = i + j;

    // jsp 中内置对象,可以直接使用, 比如 out
    out.println(i + " + " + j + " = " + res);
    // 如果要看HttpJspBase类的关系, 需要引入一个包, alt+enter

    //在java片段中,仍然是java的注释
    /*
        多行注释
     */
%>
<%--email: <%=email%>--%>
<!--html注释 -->
</body>
</html>

运行效果

 

注意事项和细节

1. jsp 页面不能像 HTML 页面, 直接用浏览器运行。只能通过浏览器访问 Tomcat 来访问jsp 页面

 

JSP 运行原理

1.   jsp 页面本质是一个 Servlet 程序, 其性能是和 java 关联的, 只是长得丑.

2.   第 1 次访问 jsp 页面的时候。Tomcat服务器会把jsp页面解析成为一个java源文件。并且对它进行编译成为.class字节码程序。

看下Cal.jsp对应的cal_jsp.java和cal_jsp.class

 

 

3.  分析下 cal_jsp.java 的源码,可以看出本质就是Servlet

提示

要看到源码和分析类图,需要加入 jasper.jar 这个包[在 tomcat/lib 下拷贝]

 

 

 

 

page 指令(常用的)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

1. language 表示 jsp 翻译后是什么语言文件, 只支持 java

2. contentType 表示 jsp 返回的数据类型,对应源码中 response.setContentType()参数值

3. pageEncoding 属性 表示当前 jsp 页面文件本身的字符集

4. import 属性 跟 java 源代码中一样。用于导包,导类

JSP 三种常用脚本

声明脚本基本语法 statement_jsp

1. 声明脚本的格式是: <%! 声明 java 代码 %>

2. 作用:定义 jsp 的需要属性、方法、静态代码块和内部类等

应用实例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp声明脚本</title>
</head>
<body>
<h1>jsp声明脚本</h1>
<%!
    //这里我们可以声明该jsp需要使用的属性,方法,静态代码块, 内部类
    //也就是给 statement.jsp 对应的 statement_jsp 类定义成员
    //1. 属性
    private String name = "nnn";
    private int age;
    private static String company;

    //2 方法
    public String getName() {
        return name;
    }
    //3. 静态代码块
    static {
        company = "字节跳动";
    }
%>
</body>
</html>

表达式脚本基本语法

1. 表达式脚本的格式是:<%=表达式%>

2. 表达式脚本的作用是:在 jsp 页面上输出数据

3. 表达式脚本中的表达式不能以分号结束。

表达式脚本应用实例

script.jsp

</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp 表达式脚本</title>
</head>
<body>
<h1>jsp 表达式脚本应用实例</h1>
    <%!
    String name = "vvv";
    %>
<hr/>
<h1>个人信息</h1>
    用户名= <%=wyx%><br/>
    工作是: <%="java 工程师"%><br/>
    得到参数= <%=request.getParameter("sex")%>
</body>
</html>

 

代码脚本基本语法

1. 代码脚本的语法是:<% java 代码%>

2. 代码脚本的作用是:可以在 jsp 页面中,编写我们需要的功能(使用 java )

3. 可以由多个代码脚本块组合完成一个完整的 java 语句。

4. 代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据

应用实例:

计算结果

Monster.java

public class Monster {
    private Integer id;
    private String name;
    private String skill;

    public Monster(Integer id, String name, String skill) {
        this.id = id;
        this.name = name;
        this.skill = skill;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

 java_code.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>演示代码脚本</title>
</head>
<body>
<h1>演示代码脚本</h1>
<%
    //创建ArrayList ,放入两个monster对象
    ArrayList<Monster> monsterList = new ArrayList<>();
    monsterList.add(new Monster(1, "牛魔王", "芭蕉扇"));
    monsterList.add(new Monster(2, "蜘蛛精", "吐口水"));
%>
<table bgcolor="#f0f8ff" border="1px" width="300px">
    <tr>
        <th>id</th>
        <th>名字</th>
        <th>技能</th>
    </tr>
    <%
        for (int i = 0; i < monsterList.size(); i++) {
            //先取出monster对象
            Monster monster = monsterList.get(i);
    %>
            <tr>
                <td><%=monster.getId()%></td>
                <td><%=monster.getName()%></td>
                <td><%=monster.getSkill()%></td>
            </tr>
            <%
        }
    %>

</table>
</body>
</html>

 

JSP 注释

 

JSP 内置对象

● 基本介绍

1、JSP 内置对象(已经创建好的对象, 直接使用 inbuild),是指 Tomcat 在翻译 jsp 页面成为Servlet 后,内部提供的九大对象,叫内置对象

2、内置对象,可以直接使用,不需要手动定义

● JSP 九大内置对象

1. out 向客户端输出数据,out.println("");

2. request 客户端的 http 请求

3. response 响应对象

4. session 会话对象

5. application 对应 ServletContext

6. pageContext jsp 页面的上下文,是一个域对象,可以 setAttribue(),作用范围只是本页面

7. exception 异常对象 , getMessage()

8. page 代表 jsp 这个实例本身

9. config 对应 ServletConfig

● 对照 Servlet 来理解就比较轻松了.

1) 一张图, 展示了 JSP 的父类 HttpJspBase 继承关系, 说明 JSP 内置对象的来源是 Servlet 和HttpJspPage

 代码实列

HiServlet.java

public class HiServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("HiServlet 被调用..");

        //servlet中可以使用哪些对象
        PrintWriter writer = response.getWriter();
        writer.println("haha");
        request.getParameter("age");
        response.setContentType("text/html;charset=utf-8");
        HttpSession session = request.getSession();
        session.setAttribute("job", "java工程师90000");
        //这个可以被多个 servlet 共享, 被多个会话共享-做网站计数器
        ServletContext servletContext = request.getServletContext();
        servletContext.setAttribute("count", 666);
        ServletConfig servletConfig = getServletConfig();
        servletConfig.getInitParameter("pwd");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

inbuild_object.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp内置对象</title>
</head>
<body>
<h1>jsp内置对象</h1>
<%
    //jsp的内置对象
    //out 类型是 JspWriter 父类就是 Writer.
    out.println("jsp out");

    //request是HttpServletRequest
    request.getParameter("age");

    //response就是 HttpServletResponse
    //response.sendRedirect("http://www.baidu.com");
    //session 就是 HttpSession
    session.setAttribute("job", "JAVA工程师");

    //application类型就是ServletContext
    application.setAttribute("name", "wyx");

    //pageContext 可以存放数据(属性), 但是该数据只能在本页面使用
    pageContext.setAttribute("age", 100);

    //exception 异常对象 使用比较少
    //page 内置对象,类似 this
    out.println("page=" + page);

    //config 内置对象的类型就是ServletConfig
    String pwd = config.getInitParameter("pwd");


%>
</body>
age: <%=pageContext.getAttribute("age")%>
</html>

JSP 域对象

JSP 四大域对象介绍[作用:存取数据]

1. pageContext (域对象,存放的数据只能在当前页面使用),

 

 

2. request (域对象,存放的数据在一次 request 请求有效)

 

 

3. session(域对象,存放的数据在一次会话有效)

 

 

4. application(域对象,存放的数据在整个 web 应用运行期间有效, 范围围更大)

 

 应用实例        

scope.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope文件</title>
</head>
<body>
<%
    //在不同的域对象中,放入数据
    //1. 因为四个域对象,是不同的对象,因此name(key) 相同时,并不会冲突
    pageContext.setAttribute("k1", "pageContext数据(k1)");

    request.setAttribute("k1", "request数据(k1)");

    session.setAttribute("k1", "session数据(k1)");

    application.setAttribute("k1", "application数据(k1)");

    //做一个请求转发的操作
    //request.getRequestDispatcher("/scope2.jsp").forward(request, response);

    //做一个重定向
    String contextPath = request.getContextPath();//返回的就是 web路径=>/jsp

    //response.sendRedirect("/jsp/scope2.jsp");
    response.sendRedirect(contextPath + "/scope2.jsp");
%>
<h1>四个域对象,在本页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>

request-k1: <%=request.getAttribute("k1")%><br/>

session-k1: <%=session.getAttribute("k1")%><br/>

application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

 scope2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope2.js</title>
</head>
<body>

<h1>在scope2页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>

request-k1: <%=request.getAttribute("k1")%><br/>

session-k1: <%=session.getAttribute("k1")%><br/>

application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

 

SP 四大域对象注意事项和细节

1. 域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存储范围

2. 从存储范围( 作用域范围看) pageContext < request < session < app

 

JSP 请求转发标签

1. 演示请求转发标签使用,如图

 

 aa.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>aa.jsp</title>
</head>
<body>
<h1>aa.jsp</h1>
<%--
1. jsp提供了很多标签,但是因为jsp不是重点,这里就演示一个常用forward
2. jsp:forward 本质就是 等价 request.getRequestDispatcher("/bb.jsp").for...
--%>
<jsp:forward page="/bb.jsp"></jsp:forward>
</body>
</html>

bb.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>bb.jsp</title>
</head>
<body>
<h1>bb.jsp页面</h1>
</body>
</html>

使用 jsp 完成一个简单的计算器,

需求 

1) 要求在前端页面对输入的 num1 和 num2 进行校验必须是整数
2) 验证成功, 提交数据给服务器, 能够显示结果
3) 点击超链接, 可以返回界面如果用户这样提交http://localhost:8080/jsp/calServletnum1=aaa&num2=90, 需要你返回 calUI.jsp , 并给出提示信

● 思路分析(程序框架图)

 calUI.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP计算器</title>
    <!--使用js+正则表达式完成数据校验-->
    <script type="text/javascript">
        function check() {
            //得到 num1 和 num2值
            var num1 = document.getElementById("num1").value;
            var num2 = document.getElementById("num2").value;

            //验证 正则表达式, 整数
            var reg = /^[-]?([1-9]\d*|0)$/;
            if (!reg.test(num1)) {//如果不满足验证条件
                alert("num1 不是一个整数");
                return false;//放弃提交
            }
            if (!reg.test(num2)) {//如果不满足验证条件
                alert("num2 不是一个整数");
                return false;//放弃提交
            }
            return true;//提交到action指定的位置
        }
    </script>
</head>
<body>
<h1>JSP计算器</h1>
<form action="<%=request.getContextPath()%>/calServlet"
      method="post" onsubmit="return check()">
    num1: <input type="text" id="num1" name="num1"> num1错误:xx <br/>
    num2: <input type="text" id="num2" name="num2"> num2错误:xx<br/>
    运算符号:
    <select name="oper">
        <option value="+">+</option>
        <option value="-">-</option>
        <option value="*">*</option>
        <option value="/">/</option>
    </select><br/>
    <input type="submit" value="提交计算">
</form>
</body>
</html>

 CalCLServlet.java

public class CalServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CalServlet 被调用...");
        //1. 是Servlet
        //2. 接收数据
        //String num1 = request.getParameter("num1");
        //String num2 = request.getParameter("num2");
        //进行转换->int
        double num1 = WebUtils.parseDouble(request.getParameter("num1"), 0);
        double num2 = WebUtils.parseDouble(request.getParameter("num2"), 0);
        String oper = request.getParameter("oper");
        double res = 0; //使用变量来接收运算结果
        //防止跳过jsp验证在这里可以在用正则表达式判断一次
        //如果错误就重定向并且提示错误让用户重新输入
        //3. 完成计算
        if ("+".equals(oper)) {
            res = num1 + num2;
        } else if ("-".equals(oper)) {
            res = num1 - num2;
        } else if ("*".equals(oper)) {
            res = num1 * num2;
        } else if ("/".equals(oper)) {
            res = num1 / num2;
        } else {
            System.out.println(oper + " 不正确...");
        }

        //4. 把结果保存到域对象[request, session, servletContext]
        //   因为一次请求对应一次计算, 所以我建议将结果保存到request
        //  把结果组织到一个字符串中., 方便我们在下一个页面显示

        String formatRes = String.format("%s %s %s = %s", num1, oper, num2, res);
        request.setAttribute("res", formatRes);

        //System.out.println("formatRes= " + formatRes);
        //5. 转发到显示页面 calRes.jsp

        request.getRequestDispatcher("/cal/calRes.jsp").forward(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

calRes.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>计算结果</title>
</head>
<body>
<h1>计算结果</h1>
<%=request.getAttribute("res")%><br/>
<%--<a href="/jsp/cal/calUI.jsp">返回重新来玩一把</a>--%>
<a href="<%=request.getContextPath()%>/cal/calUI.jsp">返回重新来玩一把~</a>
</body>
</html>