例1:在web.xml文件中配置首页 在web.xml文件中配置首页使用welcome-file-list元素,该元素能包含多个welcome-file子元素,其中每个子元素配置一个首页。
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> 当Web应用中包含index.html页面时,如果浏览器直接访问该Web应用,系统将会把该页面呈现给浏览者;当index.html页面不存在时,则由index.htm页面充当首页,以此类推。例1:简单的JSP页面
<body> <%for(int i = 0;i<7;i++){ out.println("<font size='"+i+"'>"); %> 学习java web和SSH框架</font><br> <% } %> </body>例2:Tomcat容器将上面程序编译成Servlet
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/7.0.52 * Generated at: 2017-09-04 01:41:39 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.*; import java.util.*; public final class index3_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { 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'); out.write('\n'); String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; out.write("\r\n"); out.write("\r\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"); out.write("<html>\r\n"); out.write(" <head>\r\n"); out.write(" <base href=\""); out.print(basePath); out.write("\">\r\n"); out.write(" \r\n"); out.write(" <title>欢迎</title>\r\n"); out.write("\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n"); out.write("\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n"); out.write("\t<meta http-equiv=\"expires\" content=\"0\"> \r\n"); out.write("\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n"); out.write("\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n"); out.write("\t<!--\r\n"); out.write("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\r\n"); out.write("\t-->\r\n"); out.write(" </head>\r\n"); out.write(" \t\r\n"); out.write(" <body>\r\n"); out.write(" \t"); for(int i = 0;i<7;i++){ out.println("<font size='"+i+"'>"); out.write("\r\n"); out.write(" \t\t学习java web和SSH框架</font><br>\r\n"); out.write(" \t"); } out.write("\r\n"); out.write(" </body>\r\n"); out.write("</html>\r\n"); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { 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); } } } 该Java类主要包含如下3个方法:(去除方法名中的_jsp前缀,再将首字母小写) init():初始化JSP/Servlet的方法 destory():销毁JSP/Servlet之前的方法 service():对用户请求生成响应的方法jsp注释用于标注在程序开发过程中的开发提示,不会输出到客户端
例1:页面源码展示:
<body> <%--注释内容 --%> <%--江山如此多娇 --%> <!-- HTML注释内容 --> <!-- 引无数英雄竞折腰 --> </body> <body> <!-- HTML注释内容 --> <!-- 引无数英雄竞折腰 --> </body> 结论:HTML的注释可以通过源代码查看到,但是JSP的注释是无法通过源代码查看的,进一步说明JSP注释不会被发送到客户端。例1:使用JSP声明的示例页面
</head> <%! //声明一个整形变量 private int count; //声明一个方法 public String info(){ return "hello"; } %> <body> <% //将count的值输出后加1 out.println(count++); %> <br> <% //输出info方法的返回值 out.println(info()); %> </body>例2:对应Servlet代码:
public final class index5_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { //声明一个整形变量 private int count; //声明一个方法 public String info(){ return "hello"; } } 表明:JSP页面的声明部分将转换成对应Servlet的成员变量或成员方法。 注意: 1.JSP声明部分定义的变量和方法可以使用private,public等访问控制修饰符,也可使用static修饰,将其变成类属性和类方法。但是不能使用abstract修饰声明部分的方法,因为抽象方法将导致JSP对应Servlet变成抽象类,导致无法实例化。 2.打开多个浏览器刷新该页面,发现所有客户端访问的count将是连续的,即所有客户端共享了同一个count变量。这是因为:JSP页面会编译成一个Servlet类,每个Servlet在容器中只有一个实例;在JSP中声明的变量是成员变量,成员变量只在创建实例时初始化,该变量的值将一直存在,直到实例销毁。 同时info()方法的值也可以正常输出。因为JSP声明额方法其实是在JSP编译中生成的Servlet的实例方法。例1:使用输出表达式的方式输出变量和方法返回值。
</head> <%! //声明一个整形变量 private int count; //声明一个方法 public String info(){ return "hello"; } %> <body> <!-- 使用表达式输出变量值 --> <%=count++ %> <br> <!-- 使用表达式输出方法返回值 --> <%=info() %> </body> 使用输出表达式语法替换了原来的out.println()输出语句,页面效果相同。表明:输出表达式将转换成Servlet里的输出语句。 注意:输出表达式语法后不能有分号,否则会报错所有可执行性Java代码都可以通过JSP脚本嵌入HTML页面。
<table bgcolor="#9999dd" border="1" width="300px"> <!-- java脚本,这些脚本会对HTML的标签产生作用 --> <% for(int i =0;i<10;i++){ %> <!-- 上面的循环将控制<tr>标签循环 --> <tr> <td>循环值:</td> <td><%=i %></td> </tr> <% } %> </table> 注意: 1.jsp脚本将转换成Servlet_service方法的可执行代码。这意味着在JSP小脚本部分也可以声明变量,但声明的是局部变量,并且不能使用private,public等访问控制符修饰,也不可以使用static修饰。 2.jsp页面里的所有静态内容将由service方法的输出语句来输出,这就是JSP脚本可以控制JSP页面中静态内容的原因。 3.java语法不允许在方法里定义方法,所以jsp脚本不能定义方法。例1:JSP页面执行数据库查询
<body> <% //注册数据库驱动 Class.forName("com.mysql.jdbc.Driver"); //获取数据库连接 Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/test", "root", "root"); //创建Statement Statement state = conn.createStatement(); //执行查询 ResultSet rs = state.executeQuery("select name,money from t_account"); %> <table bgcolor="#9999dd" border="1" width="300px"> <!-- 遍历结果 --> <% while(rs.next()){ %> <tr> <td><%=rs.getString(1) %></td> <td><%=rs.getString(2) %></td> </tr> <% }%> </table> </body> 注意:需要导入数据库连接jar包;调用rs.next()方法,不是next属性例1:使用info属性指定了jsp页面的描述信息,又使用getServletInfo()方法输出该描述信息。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" info="this is a jsp"%> <body> <%=getServletInfo() %> </body>例2:errorPage属性,该属性指定了当本页面发生异常时的异常处理页面。
如果jsp页面在运行中抛出未处理的异常,系统将自动跳转到errorPage属性指定的页面;如果errorPage没有指定错误页面,系统则直接把异常信息呈现给客户端浏览器。 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" errorPage="error.jsp"%> <body> <% int a = 6; int b = 0; int c = a/b; %> </body> 错误显示页面 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%> <body> <h1>系统出现异常</h1> </body>格式如下:
包含页面1: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>测试page指令的info属性</title> </head> <body> <%@ include file="index1.jsp" %> </body> </html> 被包含页面2: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>测试page指令的info属性</title> </head> <body> <h2>天气不错</h2> </body> </html> 注意:被包含页面不能定义path和basePath 变量,否则会报错:Duplicate local variable path(重复的局部变量) 如果被嵌入的文件经常需要修改,建议使用<jsp:include>操作命令,因为它是动态的include语句。 对应的Servlet类: out.write("\r\n"); out.write("\r\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"); out.write("<html>\r\n"); out.write(" <head>\r\n"); out.write(" <base href=\""); out.print(basePath); out.write("\">\r\n"); out.write(" <title>测试page指令的info属性</title>\r\n"); out.write(" </head>\r\n"); out.write(" <body>\r\n"); out.write(" \t"); out.write("\r\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"); out.write("<html>\r\n"); out.write(" <head>\r\n"); out.write(" <base href=\""); out.print(basePath); out.write("\">\r\n"); out.write(" <title>测试page指令的info属性</title>\r\n"); out.write(" </head>\r\n"); out.write(" <body>\r\n"); out.write(" \t<h2>天气不错</h2>\r\n"); out.write(" </body>\r\n"); out.write("</html>\r\n"); out.write("\r\n"); out.write(" </body>\r\n"); out.write("</html>\r\n"); 可以看出,1页面已经完全将2页面的代码融入到1页面中。其中被包含的代码并不是由1页面所生成的,而是由2页面生成的。也就是说,2页面的内容被完全融入到1页面所生成的Servlet中,这就是静态包含意义:包含页面在编译时将完全包含了被包含页面的代码。 注意:静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突,那么页面就会出错。例1:使用forward动作指令来转发用户请求
初始页面: <body> <jsp:forward page="forward_result.jsp"> <jsp:param value="23" name="age"/> </jsp:forward> </body> 转发页面: <body> <%=request.getParameter("age") %> </body> 结果显示: 23 注意: 1.从上面的结果可以看出:执行forward指令时,用户请求的地址依然没有发生改变,但页面内容却完全变为forward目标页的内容。 2.执行forwardd指令转发请求时,客户端的请求参数不会丢失。例2:执行forward时不会丢失请求参数
表单页面: <body> <form id="login" method="post" action="index11.jsp"> <input type="text" name="username"> <input type="submit" value="login"> </form> </body> forward指令页面: <body> <jsp:forward page="forward_result.jsp"> <jsp:param value="23" name="age"/> </jsp:forward> </body> 转发到页面: <body> <%=request.getParameter("age") %> <%=request.getParameter("username") %> </body> 结果显示: 23 lijisheng 结论: 1.在最终页面不仅可以输出forward指令增加的请求参数,还可以看到表单里username表单域对应的请求参数,这表明执行forward时不会丢失请求参数。 2.从表面上看,<jsp:forward.../>指令给人一种感觉,他是将用户请求“转发”到额另一个新页面,但实际上,<jsp:forward.../>并没有重新向新页面发送请求,它只是完全采用新页面来对用户生成响应--请求依然是一次请求,所以请求参数,请求属性都不会丢失。例1:动态导入
<body> <jsp:include page="index1.jsp"></jsp:include> </body> Servlet页面展示 out.write(" <body>\r\n"); out.write(" \t"); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index1.jsp", out, false); out.write("\r\n"); out.write(" </body>\r\n"); out.write("</html>\r\n"); 注意:动态导入只是使用一个include方法来插入目标页面的内容,而不是将目标页面完全融入本页面中。例2:有参数的动态导入
<body> <jsp:include page="index1.jsp"> <jsp:param value="rain" name="like"/> </jsp:include> </body> <body> <%=request.getParameter("like") %> </body> 结果展示: rain动态导入和静态导入有三点区别:
1.静态导入时将被导入页面的代码完整融入,两个页面融合成一个整体Servlet,而动态导入则在Servlet中使用include方法来引入被导入页面的内容。 2.静态导入时被导入页面的编译指令会起作用,而动态导入时被导入页面的编译指令则失去作用,只是插入被导入页面的body内容。 3.动态包含还可以增加额外的参数。 提示:forward动作指令和include动作指令十分相似,都是使用方法来引入目标页面。区别在于:forward拿目标页面替换原有页面,而include则拿目标页面插入原有原有页面。useBean的语法格式如下:
<jsp:useBean id="name" class="classname" scope="page|request|session|application"/> 其中,id属性是JavaBean的实例名,class属性确定JavaBean的实现类。scope属性用于指定JavaBean实例的作用范围,该范围有如下四个值。 1.page:该JavaBean实例仅在该页面有效。 2.request:该JavaBean实例在本次请求中有效。 3.session:该JavaBean实例在本次session中有效。 4.application:该JavaBean实例在本应用内一直有效。setProperty指令的语法格式如下:
<jsp:setProperty property="propertyName" name="BeanName" value="value"/> 其中,name属性确定需要设定JavaBean的实例名,property属性确定需要设置的属性名;value属性则确定需要设置的属性值。getProperty指令的语法格式:
<jsp:getProperty property="propertyName" name="BeanName"/> 其中,name属性确定需要输出的JavaBean的实例名,property属性确定需要输出的属性名。例1:使用这3个动作指令来操作JavaBean
<body> <jsp:useBean id="p1" class="test.Persion" scope="page"></jsp:useBean> <jsp:setProperty property="name" name="p1" value="lijisheng"/> <jsp:setProperty property="age" name="p1" value="23"/> <jsp:getProperty property="name" name="p1"/><br> <jsp:getProperty property="age" name="p1"/> </body> 结果显示: lijisheng 23 注意:对于上面的JSP页面的setProperty和getProperty标签而言,他们都要求根据属性名来操作JavaBean的属性。实际上setProperty和getProperty要求的属性名,与Java类中定义的属性有一定的差别。 例如:setProperty和getProperty需要使用name属性,但JavaBean中是否真正定义来了name属性并不重要,重要的是在JavaBean中提供了setName()和getName()方法即可。 事实上,当页面使用setProperty和getProperty标签时,系统底层是调用setName()和getName()方法来操作Persion实例的属性的。例2:不使用这三个标签实现同样功能
<body> <% Persion p1 = new Persion("lijisheng",20); //将p1放到page范围中 pageContext.setAttribute("p1", p1); %> <%=p1.getName() %><br> <%=p1.getAge() %> </body>使用useBean标签时,除在页面脚本中创建了JavaBean实例之外,该标签还会将JavaBean实例放入scope中。
pageContext.setAttribute("p1", p1); request.setAttribute("p1", p1); session.setAttribute("p1", p1); application.setAttribute("p1", p1);param指令语法格式如下:
<jsp:param value="paramValue" name="paramName"/>
