JavaWeb-Jsp

1.JSP

JSP——Java Server Page:Java服务器页面,在HTML页面中编写Java代码的页面。

绝大多数时候,我们希望响应的不是简简单单一句话,而是一个页面,我们用PrintWriter对象去写一个页面也是可以的,但缺点太明显。

所以直接返回一个页面,并且能够写Java代码就能大大简化我们的开发,这就是——JSP

当前不提倡在jsp页面中写Java代码,代替使用EL表达式。

JSP是简化Servlet编写的一种技术,它将Java代码和HTML语句混合在同一个文件中编写,只对网页中的需要动态产生的内容采用Java代码来编写,而对固定不变的静态内容采用普通静态HTML页面的方式编写。

2.JSP的认识

在JSP页面中编写的Java代码需要嵌套在<% 和 %> 中,嵌套在<% 和 %>之间的Java代码被称为脚本片段,没有嵌套在<% 和 %>之间的内容被称为JSP的模板元素。

WEB容器(WEB服务器)(Servlet引擎)(Tomcat)接收到以 .jsp为扩展名的URL的访问请求时,它将把该访问请求交给JSP引擎(Tomcat)去处理。

每个JSP页面在第一次被访问时,JSP引擎将它翻译成一个Servlet源程序(Java类),接着再把这个Servlet源程序编译成Servlet的class类文件,然后再由WEB容器(Servlet引擎)(Tomcat)像调用普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的Servlet程序——JSP本质上就是一个Servlet。

当Tomcat服务器一运行index.jsp的页面时,此时的index.jsp将会翻译成index_jsp.java类,当运行成功后index_jsp.java类会编译成index_jsp.class。 将index_jsp.java类拖拽到idea中发现,该Java类继承了HttpJspBase,而HttpJspBase是HttpServlet的子类,所以可以说明JSP本质上就是一个Servlet。

3.JSP中九个隐式对象

隐式对象(或隐含对象):在JSP当中我们没有手动声明创建,但实际存在,可以直接使用的对象。

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;
//还有request和response以及exception对象,一共9个

(1)request:客户端的请求信息被封装在request对象中,通过它才能了解用户的需求。然后做出响应
(2)response:包含了响应客户请求的有关信息,但在JSP中使用很少
(3)pageContext:页面的上下文,是PageContext的一个对象,可以从该对象中获取到其它8个隐含对象,也可以获取到当前页面的其它信息
(4)session:指的是客户端与服务器端的一次会话,从客户端连到服务器端的一个WebApplication开始,直到客户端与服务器端断开连接为止
(5)application:代表当前web应用,是ServletContext对象,能实现用户间数据的共享,可存放全局变量,它开始于服务器的启动,直到服务器的关闭,在此期间,此对象一直存在;这样在用户的前后连接或不同客户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其它用户对此的访问。服务器的启动和关闭决定了application对象的生命周期
(6)config:当前JSP对应的Servlet的ServletConfig对象,可获取该Servlet的初始化参数(开发时基本不用),需要通过映射的地址才可以
(7)out:JspWriter对象,调用out.println()可以直接把字符串打印到浏览器上
(8)page:page对象就是指向当前JSP页面本身,类型为Object,有点类似于类中的this,几乎不使用
(9)exception:该对象是一个例外对象,只有页面是一个错误页面,即isErrorPage设置为true的时候(默认为false)才能使用,否则无法编译
注意:JSP可以放置在WEB应用程序中的除了WEB-INF及其子目录外的其它任何目录中

4.JSP模板元素

JSP页面中的静态HTML内容称之为JSP模板元素(比如html,body等等),在静态的HTML内容之中可以嵌套JSP的其他各种元素来产生动态内容和执行业务逻辑。
JSP模板元素定义了网页的基本骨架,即定义了页面的结构和外观。

5.JSP表达式

JSP表达式(expression)提供了将一个java变量或表达式的计算结果输出到客户端的简化方式,它将要输出的变量或表达式直接封存在<%= 和 %>之中。
在JSP表达式中嵌套的变量或表达式后面不能有分号。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Date date = new Date();
%>
<%= date %>
</body>
</html>

6.JSP脚本片段

像片段一样的JSP表达式,嵌套在<% 和 %>中,必须全部是符合java语法的语句。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        String username = request.getParameter("username");
        response.getWriter().println("Hello:"+username);
    %>
</body>
</html>

7.**页面间跳转的2种方式---请求转发和请求重定向

(1)请求转发
请求转发需要借助于一个接口,RequestDispatcher接口,利用这个接口的forward方法实现请求转发

image.png

第一种方法(带有EL表达式${ })
前端请求页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="login2" method="post">
    user:<input type="text"  name="username">
    password:<input type="password" name="password">
    <input type="submit">
</form>
</body>
</html>

Servlet处理请求

package servlet;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;

@WebServlet(name = "Login2Servlet" , urlPatterns = "/login2")
public class Login2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理请求中文乱码问题
        request.setCharacterEncoding("utf-8");
        //处理回应中文乱码问题
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        request.setAttribute("user_name" , username);
        request.setAttribute("psd" , password);
        if(username.equals("zhangsan")) {
            RequestDispatcher dispatcher = request.getRequestDispatcher("/success.jsp");
            dispatcher.forward(request , response);
        }else{
//            RequestDispatcher dispatcher = request.getRequestDispatcher("error.jsp");
//            dispatcher.forward(request , response);
            request.getRequestDispatcher("/error.jsp").forward(request , response);
        }
    }

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

    }
}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        body{
            color:green;
        }
    </style>
</head>
<body>
    <%
        String username = (String)request.getAttribute("user_name");
    %>
    <%=username%>
    登录成功

    ${user_name}
    登录成功
    你的密码是${psd}吧
</body>
</html>

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        body{
            color: red;
        }
    </style>
</head>
<body>
    ${user_name}
    登录失败
    你的密码是${psd}吧
</body>
</html>

第二种方法,用对象进行封装和传递参数(带有EL表达式${ })

java类

package domain;

public class UserInfo {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

前端请求页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="login2" method="post">
    user:<input type="text"  name="username">
    password:<input type="password" name="password">
    <input type="submit">
</form>
</body>
</html>

Servlet处理请求

package servlet;

import domain.UserInfo;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;

@WebServlet(name = "Login2Servlet" , urlPatterns = "/login2")
public class Login2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理请求中文乱码问题
        request.setCharacterEncoding("utf-8");
        //处理回应中文乱码问题
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setPassword(password);
        if(username.equals("zhangsan")) {
            request.setAttribute("user_info" , userInfo);
            RequestDispatcher dispatcher = request.getRequestDispatcher("/success.jsp");
            dispatcher.forward(request , response);
        }else{
            request.setAttribute("user_info" , userInfo);
//            RequestDispatcher dispatcher = request.getRequestDispatcher("error.jsp");
//            dispatcher.forward(request , response);
            request.getRequestDispatcher("/error.jsp").forward(request , response);
        }
    }

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

    }
}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        body{
            color:green;
        }
    </style>
</head>
<body>
    <%
        UserInfo userInfo = (UserInfo) request.getAttribute("user_info");
    %>
    <%=userInfo.getUsername()%>
    登录成功

    ${user_info.username}
    登录成功
    你的密码是${user_info.password}吧
</body>
</html>

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <style>
        body{
            color: red;
        }
    </style>
</head>
<body>
    ${user_info.username}
    登录失败
    你的密码是${user_info.password}吧
</body>
</html>

(2)请求重定向
用HttpServletResponse的sendRedirect方法实现请求重定向
请求重定向既可以返回一个jsp还可以返回一个Servlet

image.png

java类

package domain;

public class UserInfo {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

前端请求界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="login2" method="post">
    user:<input type="text"  name="username">
    password:<input type="password" name="password">
    <input type="submit">
</form>
</body>
</html>

Servlet处理请求

package servlet;

import domain.UserInfo;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;

@WebServlet(name = "Login2Servlet" , urlPatterns = "/login2")
public class Login2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //处理请求中文乱码问题
        request.setCharacterEncoding("utf-8");
        //处理回应中文乱码问题
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setPassword(password);
        if(username.equals("zhangsan")) {
            request.setAttribute("user_info" , userInfo);

            response.sendRedirect("/test");
        }else{
            request.setAttribute("user_info" , userInfo);

            response.sendRedirect("/test");
        }
    }

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

    }
}

重定向返回一个Servlet或者Jsp 这里返回的是Servlet
重定向时 发送的请求一定是Get请求

package servlet;

import domain.UserInfo;

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 java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "TestServlet" , urlPatterns = "/test")
public class TestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("TestServlet doGet");
        response.setContentType("text/html;charset = UTF-8");
        PrintWriter  printWriter = response.getWriter();
        printWriter.println("\r\n");
        printWriter.println("<html>\r\n");
        printWriter.println("<head>\r\n");
        printWriter.println("  <title>Title</title>\r\n");
        printWriter.println("</head>\r\n");
        printWriter.println("<body>\r\n");
        printWriter.println("<h2>编程语言</h2>\r\n");
        printWriter.println("<ul>\r\n");
        printWriter.println("  <li>php</li>\r\n");
        printWriter.println("  <li>c++</li>\r\n");
        printWriter.println("  <li>java</li>\r\n");
        printWriter.println("</ul>\r\n");
        printWriter.println("</body>\r\n");
        printWriter.println("</html>\r\n");

    }
}

注意:貌似重定向与请求转发没什么区别,但实际区别非常之大。
观察用请求转发和请求重定向时地址栏的变化:请求转发时地址栏没变;请求重定向时地址栏变化了。

说明一个重要问题(本质区别):
请求转发只发出了一个请求
请求重定向发出了俩个请求

请求转发和请求重定向的目标可以是一个Servlet也可以是一个jsp
request.getRequestDispatcher("/XXXServlet").forward(request,response); 和 response.sendRedirect("/XXXServlet");只能在doGet或doPost方法中调用一次,即,在doGet或doPost方法中,只能转发或重定向到一个页面,不能到多个页面。

8.EL表达式

EL能够极大的简化我们的开发

EL全名为Expression Language,它原本是JSTL1.0为方便存取数据所自定义的语言。当时EL只能在JSTL标签中使用。到了JSP2.0之后,EL已经正式纳入成为标准规范之一。

语法
EL语法很简单,它最大的特点就是使用上很方便。接下来介绍EL主要的语法结构

${sessionAttr}  // 对应的值是字符串
${user.name}    // 通过user对象.对象属性的方式

所有EL都是以 ${ 起始、以 } 为结尾的。

EL隐含对象
如果我们在request和application中设置了同名属性怎么办?
与范围有关的隐含对象
applicationScope
sessionScope
requestScope
pageScope

请求界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <a href="login.do">登录</a>
  </body>
</html>

servlet处理请求

package servlet;

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 java.io.IOException;

@WebServlet(name = "LoginServlet" , urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("user" , "lisi");
        request.getSession().setAttribute("user" , "zhangsan");
        request.getRequestDispatcher("user.jsp").forward(request , response);
    }
}

转发页面 user.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
        <%--使得输出结果为zhangsan--%>
    ${sessionScope.user}
</body>
</html>

9.属性相关方法

(1)设置属性:void setAttribute(String name , Object o)
(2)获取指定属性:Object getAttribute(String name)
能够使用这些方法的对象有4个:pageContext,request,session,application---->这4个对象也称为域对象。

10.**域对象

域:2个维度:一份数据可以在多少个页面共享,可以在多长的时间范围内共享。

pageContext:属性的作用范围仅限于当前servlet或JSP页面
request:属性的作用范围仅限于同一个请求(考虑页面转发的情况)
session:属性的作用范围限于一次会话(浏览器打开直到关闭,称为一次会话,前提是在此期间会话没有失效),数据是用户独立的
application:属性的作用范围限于当前WEB应用,是范围最大的属性作用范围,只要在一处设置属性,在其他各处的JSP或Servlet中都可以获取,直到服务器关闭。数据所有用户共享。

package servlet;

import javax.servlet.ServletContext;
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;
import java.io.IOException;

@WebServlet(name = "ServletA", urlPatterns = "/aaa")
public class ServletA extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // pageContext代表的是当前页面(本servlet),平时几乎不用
        javax.servlet.jsp.PageContext pageContext = javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this, request, response, null
                , true, 8192, true);
        pageContext.setAttribute("pageAttr", "pageValue");

        // request域,代表一次请求,如果存在转发的情况,转发经过的各个页面,都算是本次请求
        request.setAttribute("reqAttr", "reqValue");

        // session会话作用域,从用户打开浏览器,到关闭浏览器之间
        HttpSession httpSession = request.getSession();
        httpSession.setAttribute("sessionAttr", "sessionValue");

        // application应用作用域,直到Tomcat服务器关闭,卸载本网站项目
        ServletContext servletContext = request.getServletContext();
        servletContext.setAttribute("appAttr", "appValue");

        // 转发到 ServletB
//        request.getRequestDispatcher("/bbb").forward(request , response);
        //重定向到 ServletB
        response.sendRedirect("/bbb");
    }
}
package servlet;

import javax.servlet.ServletContext;
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;
import java.io.IOException;

@WebServlet(name = "ServletB", urlPatterns = "/bbb")
public class ServletB extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

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

        javax.servlet.jsp.PageContext pageContext = javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this, request, response, null
                , true, 8192, true);
        System.out.println(pageContext.getAttribute("pageAttr"));


        System.out.println(request.getAttribute("reqAttr"));

        HttpSession httpSession = request.getSession();
        System.out.println(httpSession.getAttribute("sessionAttr"));

        ServletContext servletContext = request.getServletContext();
        System.out.println(servletContext.getAttribute("appAttr"));
    }
}

servlet中通过getAttribute(String name),获取指定属性。而jsp中使用EL表达式。

11.MVC模式

MVC
model(模型) : DataBase
view(视图):jsp页面
controller(控制器):Servlet

image.png
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352