JSP的简要概括和简单的使用

JSP的简要概括和简单的使用

一、什么是jsp以及它的底层原理

JSP这三个字母是Java Server Pages的缩写,见名知意java的服务器页面

为什么会出现jsp呢?先看一段servlet的代码:

@WebServlet("/aser")
public class AServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码格式
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write("\n");
        writer.write("\n");
        writer.write("ser\n");
        writer.write("\n");
        writer.write("\n");
        writer.write("

这是Servlet

\n"
); writer.write("\n"); writer.write("\n"); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }

中间那么大一块就在浏览器输出了一个这是Servlet,是不是很复杂,各种标签需要我们去包裹起来,要是这样开发,程序员的开发成本也太大了,于是就由此衍生了jsp,让jsp帮我们干这些繁琐的事情,来看jsp的代码如何实现上面的:

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

  
    $Title$
  
  

这是Servlet

是不是像是HTML一样的简写写法,那么jsp的底层原理到底是什么?为什么就能如此简单的实现servlet中如此复杂的代码,按说这个只能servlet来完成的,带着这个问题,看下面的源码:

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

这里是jsp被翻译出来的java类,继承了HttpJspBase类,这个又继承了HttpServlet类,于是jsp的这个类间接继承了HttpServlet类。于是,我们可以得出一个结论:

JSP其实就是Servlet程序

可以看下面的源码,_jspService方法中也是用到我们手写方式,这就是底层帮我们干了我们觉得很麻烦的事,这也很好的解释了JSP就是Servlet程序了,底层仍然是Servlet。

  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,
      			"500.jsp", 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("    $Title$\n");
      out.write("  \n");
      out.write("  \n");
      out.write("

这是主页

\n"
); out.write(" \n"); out.write("\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); } }

这就可以解释为什么它可以干Servlet的事了。

二、JSP的三大指令

  1. page 用于声明jsp : jsp=html+page指令

    page 里面常见的属性:

    1. contentType=“text/html;charset=UTF-8” 指定jsp文件的mime类型和字符集
    2. import=“java.util.*” 为jsp的脚本中的Java代码去导包
    3. errorPage=“500.jsp” 如果当前页面发生异常,就跳转到500.jsp中
    4. isErrorPage=“true” 承认自己是不是错误处理页面,如果为true就可以使用exception内置对象
  2. taglib 用于导入外部资源标签库,jstl

    作用:引入外部标签库,通常用于引入jstl标签

  3. include 静态包含,一个jsp页面可以包含另一个jsp页面

    作用:静态包含 – 两个jsp之间使用静态包含,会被tomcat服务器编译成一个servlet,可以实现脚 本互通

    a.jsp:
    <%@include file="b.jsp"%>
    <%
        System.out.println(name);
    %>
        
        
    b.jsp:
    <%
        String name = "wang";
    %>
    
        
    我们访问a.jsp时候,会打印出wang
    

三、JSP的脚本方式

  1. <%! 代码 %> 声明脚本

    这种方式,用的还是比较少的,一般用来定义属性和方法,也可以写静态代码块,内部类什么的

  2. <%

    java代码

    %>

    这种方式用的比较多,这是代码脚本,因为编译之后,全部都在_jspService方法中

  3. <%=表达式%>表达式脚本

    这用用的比较多,可以看下面的例子:

    <%
    pageContext.setAttribute("key1","pageContext域");
    
    String key1 = (String) pageContext.getAttribute("key1");
    out.write(key1);
    %>
    
    pageContext:<%=pageContext.getAttribute("key1")%>

    上面就可以看出来这种脚本的强大之处了吧,直接可以输出到页面上,非常方便。

四、JSP的九大内置对象

九大对象如下:

request 请求对象
response 响应对象
pageContext jsp的上下文对象
session 会话对象
application ServletContext对象
config ServletConfig对象
out jsp输出流对象
page 指向当前jsp的对象
exception 异常对象

这个看一下就行了,知道各个对应什么对象就可以。

五、JSP四大域对象

域对象 对应的类 作用
pageContext PageContextImpl类 只在当前的jsp界面内起作用
request HttpServletRequest类 只在一次请求内起作用
session HttpSession类 只在一次会话内有用,关闭浏览器会话结束
application ServletContext类 只要web工程没停止,整个范围内都有起作用

上面的作用有限顺序从小到大:

pageContext request session application

例子:

a.jsp
<%
/*pageContext ====>>> request ====>>> session ====>>> application*/
    //向着四个域中分别保存数据
pageContext.setAttribute("key1","pageContext域");
request.setAttribute("key2","request域");
session.setAttribute("key3","session域");
application.setAttribute("key4","application域");
%>
<%--看这四个域中是否有值--%>
pageContext:<%=pageContext.getAttribute("key1")%>
request:<%=request.getAttribute("key2")%>
session:<%=session.getAttribute("key3")%>
application:<%=application.getAttribute("key4")%>
<%--转发到b.jsp--%> b.jsp <%--看这四个域中是否有值--%> pageContext:<%=pageContext.getAttribute("key1")%>
request:<%=request.getAttribute("key2")%>
session:<%=session.getAttribute("key3")%>
application:<%=application.getAttribute("key4")%>

你可能感兴趣的:(jsp,java)