Java Web入门之jsp要点

一. 基本

第一次请求JSP页面的执行过程

jsp标签说明

JSP元素 表达形式
表达式 <%= 表达式 %>
程序段 <% java代码段 %>
声明 <%! java变量或方法声明 %>
注释 <%– 注释内容 –%>
(编译)指令 <%@ … %>
动作(指令) <% jsp:动作… %>

一个简单的例子

jsp源代码first.jsp

<%@ page language="java" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="utf-8" %>
<html>
<head>
    <title>first jsp page</title>
</head>
<body>
    <%! int count = 0; public int add(int a, int b) { return a+b; } %>
    count = <%=count++%><br>
    <% String welcome = "WELCOME"; int font = 0; for (int i=0; i<7; ++i) {%><font size=<%=++font%>><%=welcome.charAt(i)%></font><%}%>
</body>
</html>

被jsp引擎翻译成的java代码(tomcat 7)first_jsp.java

/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/7.0.59 * Generated at: 2015-04-14 05:30:40 UTC * Note: The last modified time of this file was set to * the last modified time of the source file after * generation to assist with modification tracking. */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class first_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {

    int count = 0;
    public int add(int a, int b)
    {
        return a+b;
    }

  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 javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

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

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  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 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("\r\n");
      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("\t<title>first</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t");
      out.write("\r\n");
      out.write("\tcount = ");
      out.print(count++);
      out.write("<br>\r\n");
      out.write("\t");

    String welcome = "WELCOME";
    int font = 0;
    for (int i=0; i<7; ++i) {
      out.write("<font size=");
      out.print(++font);
      out.write('>');
      out.print(welcome.charAt(i));
      out.write("</font>");
      }
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } 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);
    }
  }
}

对比之下可发现,<%! %>标签内定义的变量和方法成为了类的成员变量和成员方法,<% %>标签内定义的变量成为了_jspService函数的局部变量。而且访问first.jsp的时候,count会一直增加,即使更换浏览器后继续访问,这说明tomcat在生成这个类的实例之后,会一直存储着,直到tomcat关闭。所以<%! %>标签内定义的变量和方法加不加static关键字都是无所谓的。

java代码中的out.print()和out.write(),作用都是输出字符串,不同之处是:
out.print()方法,将各种数据转换成字符串的形式输出,参数是一个java对象;
out.write()方法,参数必须是字符/字符数组/字符串等与字符相关的数据。

参考文献

JSP起源、JSP的运行原理、JSP的执行过程
http://blog.csdn.net/fengdongkun/article/details/8159381
out.print和out.write
http://lixh1986.iteye.com/blog/1757126

二. 编译指令

编译指令用来告诉引擎如何处理jsp页面中的某些部分。
基本语法格式是<%@ 编译指令名 属性名="属性值" %>,属性名区分大小写。
1. page
用来设置整个jsp页面的相关属性和功能
2. include
用于通知jsp引擎在翻译当前jsp页面时将其他文件中的内容与当前jsp页面合并,转换成一个Servlet源文件
3. taglib
引入一个标签库或自定义标签,并定义它们的前缀

三. 动作指令

动作指令是动态执行的指令,运行时的脚本动作。
1. jsp:include
用于动态引入一个jsp页面
2. jsp:useBean动作
使用JavaBean
3. jsp:getProperty
获取JavaBean实例的属性值
4. jsp:setProperty
修改JavaBean实例的属性值
5. jsp:forward
执行页面转向,将请求的处理转发到下一个页面
6. jsp:param
用于传递参数,必须与其他支持参数的标记一起使用
7. jsp:plugin
用于下载JavaBean或Applet到客户端执行

四. 隐含对象

jsp文件中共有9个隐含的java对象,其中8个在上边的java代码里已有体现,6个在_jspService函数里定义,request和response是_jspService的参数。
至于exception对象,当jsp页面用

<%@ page isErrorPage="true" %>

被指定为errorPage后,_jspService也会定义exception对象,如下:

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    java.lang.Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
    if (exception != null) {
        response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;

pageContext由request和response得到,page就是对象本身,其他对象都由pageContext得到。

这9个隐含对象分别为:

对象 说明
page 代表当前页面
request 代表由用户提交请求而触发的request对象
response 代表由用户提交请求而触发的response对象
pageContext 提供了对JSP页面内所有的对象及名字空间的访问
session 代表会话对象,在发生HTTP请求时被创建
application
out 主要用来向客户端输出内容,同时管理应用服务器输出缓冲区
config 代表当前页面配置
exception 代表异常

Cookie对象

它不是jsp的内置对象,但它很有用,一般和session配合使用,使用它时需要显式创建。
Cookie类有如下几个方法:

setMaxAge(int expiry);
设置Cookie的存在时间,正值表示Cookie将在多少秒后失效,负值表示当浏览器关闭时,Cookie将被删除,零值表示要删除该Cookie。
setDomain(String domain);
设置Cookie在哪个域名下可见。
setPath(String path);
设置Cookie在当前域名的哪个路径下可见,如果设置为"/"则在当前域名下的所有路径均可见。如果未设置,则在哪个页面产生的就只能在哪个页面访问。
Cookie[] getCookies();
获得Cookie数组。

将cookie存储到客户端的方法是:

    Cookie cookie = new Cookie("username", "jack");
    cookie.setMaxAge(60*60);//设定存活期为1小时
    cookie.setDomain(".csdn.net");
    cookie.setPath("/");
    response.addCookie(cookie);

读取客户端cookie的方法是:

    if(request.getCookies()!=null)
    {
        for(Cookie cookie:request.getCookies())
        {
            String name = cookie.getName();
            String value = cookie.getValue();
            out.println(name+"+"+value+"<br>");
        }
    }

五. 乱码问题

文件编码

<%@ page contentType="text/html;charset=gbk" pageEncoding="utf-8" %>
里的pageEncoding是jsp文件本身的编码,contentType是指服务器发送给客户端的html的编码,它必须和html代码里的
<meta http-equiv=Content-Type content="text/html;charset=gbk">
设置相符合才行。

表单提交

在提交表单时(get或post方法),使用request.getParameter方法获取表单控件值时可能会出现乱码。
1. get方法
get方法传的参数里有中文时会在URI里出现带%的一串数字,这是将汉字和特殊符号编码为了ISO-8859-1,所以会出现乱码。
在服务器端可以先获取字符串的字节码,然后再转换为支持中文的编码:

String newstrig = new String(oldstring.getBytes("ISO-8859-1"), "utf-8");

也可以在tomcat的配置文件$TOMCAT/conf/server.xml里的将URIEncoding改为utf-8:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8" />

然后重启tomcat就可以正确处理get方法提交的数据了。
2. post方法
如果html页面用的是utf-8编码,可以在处理页面通过设置

request.setCharacterEncoding("utf-8");

来解决,功能是设置请求对象的字符编码。如果html页面用的是gbk编码,将utf-8改成gbk即可。
response.setCharacterEncoding("utf-8")用来设置回应信息的字符编码。
可以编写一个过滤器,来执行这个设置,这样就不用在每个页面都加上这条语句了。

当然,也可以仿照get方法的处理方法:

String user0 = request.getParameter("user");
String user = new String(user0.getBytes("ISO-8859-1"), "utf-8");

你可能感兴趣的:(jsp)