JSP:java server page, java服务器端页面,在html中编写java代码。

1.为什么会有jsp

jsp是同servlet编写的一种技术,它将java代码和html代码语句混合在同一个文件中编写
只对网页中的要动态产生的内容采用java代码编写,而对固定不变的静态内容采用普通的html代码编写。

2.jsp的hello程序

新建jsp页面,在 <% %> 之间编写java代码即可。

这个jsp文件可以放在web应用的任何目录(除了WEB-INFO目录)

3.jsp的运行原理

$ ls  /tomcat/_day_29/work/Catalina/localhost/hello/org/apache/jsp/ -lh                                            

total 32K
-rw-rw-r-- 1 mamh mamh 6.1K 81 16:30 hello2_jsp.class
-rw-rw-r-- 1 mamh mamh 5.3K 81 16:30 hello2_jsp.java
-rw-rw-r-- 1 mamh mamh 7.0K 829 13:41 index_jsp.class
-rw-rw-r-- 1 mamh mamh 6.9K 829 13:41 index_jsp.java

jsp的本质上其实是一个servlet。每个jsp页面第一次被访问的时候,jsp引擎将他翻译为一个servlet。然后接着把这个servlet源代码程序编译为class文件。

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  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 static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = new java.util.HashSet<>();
    _jspx_imports_classes.add("com.atguigu.javaweb.HelloServlet");
    _jspx_imports_classes.add("com.atguigu.javaweb.Person");
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  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 java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}

    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("\n");
      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("    <title>$Title$</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");
      out.write("<a href=\"upload.jsp\">upload</a>\n");
      out.write("<br/><br/>\n");
      out.write("<a href=\"download.jsp\">download</a>\n");
      out.write("\n");



    //9 个隐含对象
    //1.HttpServletRequest类的一个对象
    String username = request.getParameter("username");
    System.out.println(username);

    //2.HttpServletResponse类的一个对象,这个几乎不会调用
    Class clazz = response.getClass();
    System.out.println(clazz);

    //3.PageContext,页面的上下文,重要的一个对象。
    // 可以从改对象中获取页面所有信息,可以获取其他的8个隐含对象(后面学习自定义标签使用它)
    HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
    System.out.println(req == request);

    //4.session,HttpSession类的一个对象,代表浏览器和服务器的一次会话
    System.out.println("session ID = " + session.getId());


    //5.application,代表当前web应用,可以获取web应用的初始化参数
    System.out.println(application.getInitParameter("user"));


    //6.config,当前jsp对象的servlet的ServletConfig对象,几乎不用
    System.out.println(config.getInitParameter("hellojsp.password"));


    //7.out, JspWriter 对象 可以直接调用out.println(),可以把字符串都打印到页面上
    out.println(config.getInitParameter("hellojsp.password"));
    out.print("<br/>");
    out.println("session ID = " + session.getId());


    //8.page是Obejct的对象,等于是this,    final java.lang.Object page = this;
    //指向当前jsp对象的一个引用,但是他是一个Object类型只能使用Object 类的方法,几乎不用
    out.print("<br/>");
    out.print(this);
    out.print("<br/>");
    out.print(page);

    //9.exception  只有在error 页面才可以使用



      out.write("\n");
      out.write("\n");
      out.write("\n");
      out.write("</body>\n");
      out.write("</html>\n");
      out.write("\n");
      out.write("\n");
      out.write("</body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              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);
    }
  }
}

4.jsp中的9个隐含对象

pageContext, request, session, application(对属性作用域的范围从小到大)这几个很重要
out, response, config, page这几个不常用

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 {
      pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();

      //这下面是我们自己的代码

1).request

HttpServletRequest类的一个对象

    String username = request.getParameter("username");
    System.out.println(username);

2).response

HttpServletResponse类的一个对象,这个几乎不会调用

    Class clazz = response.getClass();
    System.out.println(clazz);

3).pageContext

,页面的上下文,重要的一个对象。

    // 可以从该对象中获取页面所有信息,可以获取其他的8个隐含对象(后面学习自定义标签使用它)
    HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
    System.out.println(req == request);

4).session

HttpSession类的一个对象,代表浏览器和服务器的一次会话,

    System.out.println("session ID = " + session.getId());

5).application

代表当前web应用,可以获取web应用的初始化参数
它就是 ServletContext 的对象。

    System.out.println(application.getInitParameter("user"));

6).config

当前jsp对象的servlet的ServletConfig对象,几乎不用
在web.xml 中配置一下这个初始化参数

    <servlet>
        <servlet-name>hellojsp</servlet-name>
        <jsp-file>/index.jsp</jsp-file>
        <init-param>
            <param-name>hellojsp.password</param-name>
            <param-value>hellojsp1234569273498271394723094723984134</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>hellojsp</servlet-name>
        <url-pattern>/index.jsp</url-pattern>
    </servlet-mapping>

在index.jsp文件中获取初始化参数

    System.out.println(config.getInitParameter("hellojsp.password"));

访问需要访问映射的那个地址

http://localhost:8080/hello/indexjsp

7).out

JspWriter 对象 可以直接调用out.println(),可以把字符串都打印到页面上

    out.println(config.getInitParameter("hellojsp.password"));
    out.print("<br/>");
    out.println("session ID = " + session.getId());

8).page

是Obejct的对象,等于是this, final java.lang.Object page = this;

    //指向当前jsp对象的一个引用,但是他是一个Object类型只能使用Object 类的方法,几乎不用
    out.print("<br/>");
    out.print(this);
    out.print("<br/>");
    out.print(page);
this:    org.apache.jsp.index_jsp@4368ebb3
page:    org.apache.jsp.index_jsp@4368ebb3 

9).exception

只有在error 页面才可以使用

只有主动声明这个页面是isErrorPage=true的页面上才可以使用

<%@ page isErrorPage="true" %>

5.jsp语法

1)jsp模板元素

jsp页面中的静态html元素称之位模板元素

2)jsp表达式(重要内容)

<%
    //1.jsp 表达式可以将java 变量或java 表达式直接在页面上面输出
    Date date = new Date();
    out.print(date);      //可以这样写  
%>
<%= date %><!-- 还可以这样写 前提是要有这个date变量,这个就是jsp的表达式 -->

3) jsp脚本片段

位于jsp页面中的<%   %>之间的代码就是脚本片段

<%
    String ageStr = request.getParameter("age");
    Integer age = Integer.parseInt(ageStr);

    if (age >= 18) {
        out.print("成人");
    } else {
        out.print("未成年");
    }
%>

也可以像下面这样来写,这就是所谓的脚本片段。多个脚本片段可以互相访问。
脚本片段的代码最后会翻译到jspService()方法里面。

<%
    String ageStr = request.getParameter("age");
    int age = 0;
    try {
        age = Integer.parseInt(ageStr);
    } catch (Exception e) {

    }
    if (age >= 18) {
%>
        成人
<%
    } else {
%>
        未成年
<%
    }


%>

上面的代码最后会被翻译为:
    String ageStr = request.getParameter("age");
    int age = 0;
    try {
        age = Integer.parseInt(ageStr);
    } catch (Exception e) {

    }
    if (age >= 18) {
      out.write("\n");
      out.write("成人\n");
    } else {
      out.write("\n");
      out.write("未成年\n");
    }

4)jsp声明

一般不用。

jsp声明将java代码封装在<%!   %>之间,它里面的代码将被插入到servlet的jspService()方法的外面。
如果在hello2.jsp 里面加入下面代码
<%!
    void test(){
        System.out.println("this is test method");
    }

%>

上面的声明会在类里面生成一个方法的。会在hello2_jsp这个类里面有这个方法。

public final class hello2_jsp extends org.apache.jasper.runtime.HttpJspBase

    void test() {
        System.out.println("this is test method");
    }
}

5)注释

jsp注释可以阻止java代码的执行。

<!--  这个是html注释-->
<%-- 这个jsp注释   --%>  

6.和属性相关的方法

1) 四个方法

    public abstract void setAttribute(String var1, Object var2);

    public abstract Object getAttribute(String var1);

    public abstract void removeAttribute(String var1);

    Enumeration<String> getAttributeNames();

2)pageContext,request,session,application 这4个对象都有这几个属性的方法

pageContext 属性的作用范围仅限于当前jsp页面。
request 属性的作用范围仅限于同一个请求。(在请求转发的情况下可以跨页面获取属性的)
session 属性的作用范围仅限于一次会话,
application 属性的作用范围限于当前web应用,是范围最大的,只要在一处设置,其他各个地方都可以获取到。

<%
    //只有这4个可以设置属性,这4个称之为域对象,设置属性
    //属性作用范围仅仅限于当前页面
    pageContext.setAttribute("p", "pageContextValue");

    //仅限于同一个请求
    request.setAttribute("r", "requestValue");

    //作用范围限于一次会话,浏览器打开直道关闭,在此期间会话不失效的前提下。
    session.setAttribute("s", "sessionValue");

    //限于当前web应用,全局的范围,范围最大
    application.setAttribute("a", "applicationValue");
%>

<br><br>
pageContext: <%= pageContext.getAttribute("p") %>
<br><br>
requestContext: <%= request.getAttribute("r") %>
<br><br>
sessionContext: <%= session.getAttribute("s") %>
<br><br>
applicationContext: <%= application.getAttribute("a") %>
<br><br>

7.请求转发和重定向


@WebServlet(name = "forwardServlet", urlPatterns = {"/forwardServlet"})
public class ForwardServlet 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("forward servlet do get ....");

        //转发这里的属性可以传递给下个servlet,应为请求转发是一个request
        request.setAttribute("r", "forward servlet");
        System.out.println("forward servlet do get ...." + request.getAttribute("r"));


        //请求的转发
        //1.调用HttpServeltRequest 的 getRequestDispatcher(addr) 方法,传入要转发的地址
        String path = "forwardDestServlet";
        RequestDispatcher requestDispatcher = request.getRequestDispatcher(path);

        //2.调用HttpServeltRequest 的 forward() 进行请求的转发
        requestDispatcher.forward(request, response); //这样就转发到forwardDestServlet这里了

    }
}
@WebServlet(name = "forwardDestServlet",urlPatterns = {"/forwardDestServlet"})
public class ForwardDestServlet 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("forward dest servlet do get ....");

        System.out.println("ForwardDestServlet servlet do get ...." + request.getAttribute("r"));


        PrintWriter out = response.getWriter();
        out.println("dest page.....");

    }
}

请求转发和重定向的区别

请求转发和重定向的区别      
    请求转发地址栏不发生变化.
    转发是一个请求,
    请求转发只能发到当前web应用的某个资源,不能转发出去.
    对转发而言斜杠代表的是当前应用的根目录.

    重定向会改变的.
    重定向是2个请求.
    重定向可以到任何资源.
    对于重定向斜杠代表是站点的/

在这个基础上来讲mvc设计模式(请求转发)

8.jsp指令

指令放在<%@ %> 直接,有3个执行,page,taglib,include

多个属性可以写到一个指令里面,也可以分开写到多个指令中。
page指令的作用都在整个jsp页面,一般放到jsp页面的开头几行。

<%@ page 属性名=“属性值” %>

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

<%@taglib prefix=""%>

<%@include file=""%>

1)page指令

<%@page import="java.lang.Integer" %> 指定导入的java类。
<%@page session="true|false" %> 作用是配置是否可以使用session隐含对象。
访问当前页面是否要生成httpsession对象。
<%@ page errorPage="/error.jsp" %>
<%@ page isErrorPage="true" %>
从当前页面出错跳转到error.jsp的时候 内部其实用的是转发。

如何是客户端不能直接访问某个页面,对于tomcat来说,web-info下面的文件是不能直接访问的,隐私文件。可以通过转发来访问web-info下面的隐私文件。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
contentType指定当前页面的内容类型,也可以指定编码
实际会被翻译为:      response.setContentType("text/html;charset=UTF-8");
通常情况下取值为text/html;charset=UTF-8
<%@page pageEncoding="utf-8" %>指定当前jsp页面的编码,通常和contentType里面一致。
<%@page isELIgnored="true" %> 指定当前jsp页面是否可以使用EL表达式,通常取值true

2)include指令
include会被文件的所有内容包含进来的。静态包含,源码级别包含。
翻译后是一个java源文件。
相对路径问题,斜杠开头表示当前web应用的根目录。

String str= "";
<%@include file="attr1.jsp"%>
include之前声明的变量在包含的那个attr1.jsp文件中是可以使用的。这个在动态包含中是不生效的。

3)jsp:include 标签

动态包含,这个会生成2个java文件的。
<jsp:include page="attr1.jsp"/>

翻译为这样的一个语句:org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "attr1.jsp", out, false);


9.jsp标签

<jsp:include page="attr1.jsp"/>
使用这种标签的方式可以使用子标签<jsp:param> 像下一个jsp页面传入一些参数。
在jsp页面转发,直接这样写标签,不用再写java代码了。
<jsp:forward page="attr1.jsp" />
翻译为:
      if (true) {
        _jspx_page_context.forward("attr1.jsp");
        return;
      }

使用这种标签的方式可以使用子标签<jsp:param> 像下一个jsp页面传入一些参数。
<jsp:forward page="attr1.jsp">
    <jsp:param name="username" value="xxxx"/>
</jsp:forward>
在attr1.jsp里面可以使用request.getParameter("username")获取到请求的参数。

10.

11.

12.

13.

14.

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐