一、
通过Servlet进行整个网站的开发是可以的。 不过在Servlet中输出html代码,特别是稍微复杂一点的html代码,就会给人一种很酸爽的感觉。
如果能够直接使用Html代码,然后在html中写java代码,就好了~
JSP … 就可以干这个事情。
1.hello.jsp
在web目录下下新建一个文件hello.jsp
访问网页
http://127.0.0.1/hello.jsp
注: 不需要重启tomcat
<%@page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
你好 JSP
<br>
<%=new Date().toLocaleString()%>
2.代码解释
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
是JSP的<%@page指令
contentType=”text/html; charset=UTF-8”
相当于response.setContentType(“text/html; charset=UTF-8”); 通知浏览器以UTF-8进行中文解码
pageEncoding="UTF-8" //如果jsp文件中出现了中文,这些中文使用UTF-8进行编码
import="java.util.* //导入其他类,如果导入多个类,彼此用,逗号隔开
<%= > 输出
<%=new Date().toLocaleString()%>
输出当前时间,相当于在Servlet中使用response.getWriter()进行输出
response.getWriter().println(new Date().toLocaleString());
二、JSP 转译为SERVLET
为什么JSP可以在html中运行java代码? 这是因为JSP被转译成了Servlet
1.执行过程
- 把 hello.jsp转译为****hello_jsp.java
- hello_jsp.java 位于
c:\tomcat\work\Catalina\localhost_\org\apache\jsp - hello_jsp.java**是一个servlet**
- 把hello_jsp.java 编译为hello_jsp.class
- 执行hello_jsp,生成html
- 通过http协议把html 响应返回给浏览器
2.hello_jsp.java 为什么是Servlet
在Servle章节中,我们说HelloServlet是一个Servlet,不是因为它的类名里有一个”Servlet”,而是因为它继承了 HttpServlet
打开转译hello.jsp 后得到的hello_jsp.java,可以发现它继承了类
(c:\tomcat\work\Catalina\localhost_\org\apache\jsp\hello_jsp.java)
org.apache.jasper.runtime.HttpJspBase
而HttpJspBase 继承了HttpServlet
所以我们说hello_.jsp.java 是一个Servlet
三、界面元素
1.jsp由这些页面元素组成:
- 静态内容
就是html,css,javascript等内容 - 指令<%@%>
以<%@开始 %> 结尾,比如<%@page import=”java.util.*”%> - 表达式 <%=%>
用于输出(out.println)一段html - Scriptlet<%%>
在<%%> 之间,可以写任何java 代码 - 声明<%!%>
在<%!%> 之间可以声明字段或者方法。但是不建议这么做。 - 动作jsp:
<jsp:include page="Filename" >
在jsp页面中包含另一个页面。在包含的章节有详细的讲解 - 注释 <%– – %>
不同于 html的注释 通过jsp的注释,浏览器也看不到相应的代码,相当于在servlet中注释掉了
2.<%=%>和 <%out.println()%>
<%="hello jsp"%>
就相当于
<%out.println("hello jsp");%>
out是jsp的隐式对象,可以直接使用。一共有9种隐式对象,请参考 隐式对象 章节
注: <%=%> 不需要分号结尾,<%%> 需要以分号结尾,和java代码一样
3.for循环
结合for循环在jsp里输出html是常见的做法。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%
List<String> words = new ArrayList<String>();//里面是java代码
words.add("today");
words.add("is");
words.add("a");
words.add("great");
words.add("day");
%>
<table width="200px" align="center" border="1" cellspacing="0">
<%for (String word : words) {%>
<tr>
<td><%=word%></td>//输出一个word
</tr>
<%}%>
</table>
四、INCLUDE包含其他页面的两种方式,以及其区别
每个网页的最下方都有 版权声明等信息。 如果不使用包含,那么每个网页都需要单独写,如果版权声明要修改,则需要很大的工作量。
使用include的办法,只需要准备一个footer.jsp,然后在其他页面包含footer.jsp即可。
修改的时候,只需要修改footer.jsp所有的页面就都修改了,维护成本降低了很多。
include有两种方式1.指令include和2.动作include
1.首先准备一个footer.jsp
<hr>
<p style="text-align:center">copyright@2016
</p>
2.通过指令include
@include
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
你好 JSP
<%@include file="footer.jsp" %>
3.通过动作include
通过动作
<jsp:include page="footer.jsp" />
在hello.jsp中包含该页面
<jsp:include page="footer.jsp" />
4.指令include和动作include的区别(插入与传参)
通过之前的学习知道,JSP最后会被转译成Servlet
如果是指令include
<%@include file="footer.jsp" %>
footer.jsp的内容会被插入到 hello.jsp 转译 成的hello_jsp.java中,最后只会生成一个hello_jsp.java文件
如果是动作include
<jsp:include page="footer.jsp" />
footer.jsp的内容不会被插入到 hello.jsp 转译 成的hello_jsp.java中,还会有一个footer_jsp.java独立存在。 hello_jsp.java 会在服务端访问 footer_.jsp.java,然后把返回的结果,嵌入到响应中。
5.传参
因为指令<%@include 会导致两个jsp合并成为同一个java文件,所以就不存在传参的问题,在发出hello.jsp 里定义的变量,直接可以在footer.jsp中访问。
而动作其实是对footer.jsp进行了一次独立的访问,那么就有传参的需要。
如本例:
1. 在hello.jsp中使用动作<jsp:include
,并通过<jsp:param
带上参数
<jsp:include page="footer.jsp">
<jsp:param name="year" value="2017" />
</jsp:include>
- 在footer.jsp中,使用request.getParameter(“year”)取出year
hello.jsp如下
<%@page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
你好 JSP
<%=new Date().toLocaleString()%>
<jsp:include page="footer.jsp">
<jsp:param name="year" value="2017" />
</