jsp
jsp
1.jsp是为Servlet编写的一种技术,它将java代码和HTML语句混合在一个文件编写
只对网页的要动态产生的内容用java代码编写,而对固定不变的静态内容采用普通的静态HTML页面方式编写
(Java Server Page 服务器端网页 在HTML页面中编写java代码)
2.jsp可以放置在WEB应用程序中除了WEB-INF目录下的任何目录中
jsp页面的访问路径与普通的HTML页面的访问路径也完全一样
3.jsp本质上是一个Servlet
每个jsp页面在第一次被访问时,jsp引擎将他翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的class文件(在D:\software\apache-tomcat-8.0.52\work\Catalina\localhost\jsp\org\apache\jsp)
然后再由WEB容器(Servlet引擎)像调用Servlet程序一样的方式来装载和解释执行这个由jsp页面翻译成的Servlet程序
hello.jsp的java部分源码
public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports{
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 {
}
}
HttpJspBase类
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
@Override
public final void init(ServletConfig config)
throws ServletException
{
super.init(config);
jspInit();
_jspInit();
}
@Override
public final void destroy() {
jspDestroy();
_jspDestroy();
}
@Override
public final void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
_jspService(request, response);
}
}
4.jsp页面隐含变量
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;
//使用<%%>编写的代码在此位置,可以用到request,response,pageContxet,session,application,config,out,page这8个内置对象(实际上还可以使用exception的隐含对象)
内置对象:没有声明就可以使用的对像,就是 内置对象。
1)request:是 HttpServletRequest的一个对象
http://localhost:8080/demo-servlet/hello.jsp?name=wjc
<%
System.out.println(request.getParameter("name"));//wjc
%>
2)response:是 HttpServletResponse的一个对象(在jsp中几乎不用)
<%
response.getWriter().println("we4r5tyuioqwertyui");
System.out.println(response instanceof HttpServletResponse);//true
%>
3)pageContxet:页面的上下文,是PageContext的一个对象,可以从该对象中获取到其他8个隐含对象.
也可以从中获取到当前页面的其他信息
System.out.println(pageContext instanceof PageContext);//true
pageContxet.getSeesion();
pageContxet.getRequest();
4)Session:代表浏览器和服务器的一次会话,是HttpSession的一个对象
5)application:代表当前WEB应用。是ServletContext对象
<context-param>
<param-name>ggx</param-name>
<param-value>kkx</param-value>
</context-param>
System.out.println(application.getInitParameter("ggx"));//kkx
6)config是ServletConfig对象(开发时几乎不用)
<servlet>
<servlet-name>sd</servlet-name>
<jsp-file>/hello.jsp</jsp-file>
<init-param>
<param-name>ll</param-name>
<param-value>po</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>sd</servlet-name>
<url-pattern>/ff.s</url-pattern>
</servlet-mapping>
http://localhost:8080/demo-servlet/ff.s?name=wjc
System.out.println(config.getInitParameter("ll"));//po
7)out:JspWriter对象,调用out.println()可以直接把字符串打印到浏览器上。
public abstract class JspWriter extends java.io.Writer
out.println(request.getParameter("name")+"<br/>");
8)page:指向当前jsp对应的Servlet对象的引用,但为Object类型,只能调用Object类的方法(几乎不用)
out.println(this+"<br/>");//org.apache.jsp.hello_jsp@125fd2d
out.println(page);//org.apache.jsp.hello_jsp@125fd2d
9)exception:在声明了page指令的isErrorPage="true"时,才可以使用
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
exception.getMessage();
%>
</body>
</html>
5.和属性相关的方法
Object getAttribute(Stirng name):获取指定的属性
Enumeration getAttributeNames():获取某一个作用域对象的所有属性名
removeAttribute(Stirng name):移除特定的属性
void setAttribute(String name,Object o):设置属性
6.pageConext,request,session,application能调用上面属性的方法
pageContext属性的作用范围仅限于 -- 当前jsp页面
request属性的作用范围仅限于 -- 同一个请求 从jsp到Servlet获取不到 从Servlet到jsp用请求转发可以获取到
session:属性的作用范围仅限于 -- 一次会话 (浏览器(是指360或者ie)打开知道关闭称之为一次会话 -- 在此之间会话不失效)
application:属性的作用范围仅限于 -- 当前WEB应用(我的理解是只要服务器不关闭一直在),作用范围最大,只要在一处设置值,在其他
jsp或者Servlet中就能获取到
7.请求转发和重定向
1)本质区别:请求转发只发出了1个请求,而重定向则发出来2个请求
就像小红找小明借钱
请求转发 小红找小明借钱 小明可以向别人借钱然后给小红 (小红一共借了1次钱)
请求重定向:小红找小明借钱 小明说小哈有钱 小红又向小哈借钱 (小红一共借了2次钱)
具体:
请求转发:地址栏初次发出请求的地址.
请求重定向:地址栏不再是初次发出请求的地址,地址栏为最后相应的那个地址
请求转发:在最终的Servlet中,request对象和中转的对像是同一个对像
请求重定向:在最终的Servlet中,request对象和中转的对像不是同一个对像
请求转发:只能转发到当前WEB应用的资源
请求重定向:可以重定向到任何资源
<%
//请求转发的代码
//HTTP Status 404 - /demo-servlet/http://www.baidu.com
request.getRequestDispatcher("http://www.baidu.com").forward(request, response);
//请求重定向的资源
//跳到百度主页
response.sendRedirect("http://www.baidu.com");
%>
请求转发:/ 代表当前WEB应用的根目录 (http://localhost:8080/demo-servlet/)
重定向:/ 代表当前WEB站点的根目录 (http://localhost:8080/)
<%
//请求转发的代码
// http://localhost:8080/demo-servlet/a.jsp
request.getRequestDispatcher("/a.jsp").forward(request, response);
//请求重定向的资源
// http://localhost:8080/a.jsp
response.sendRedirect("/a.jsp");
%>
jsp指令
1.<%@指令 属性名="值"%>
<%@ page language="java"%>
2.在目前的JSP中,定义了page,include,taglib这3种指令
3.page指令
1)page指令出现在jsp页面的任何位置都可以,page指令最好放在整个jsp页面的起始位置
2)page指令常用的属性
1-import属性:指定当前jsp中需要导入的类
<%@page import="java.util.Date"%>
注意下面几个包是jsp自带的不需要导入的
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
如:HttpServletRequest类不需要导入
2-session属性:取值为true或者false 指定当前页面的session隐藏变量是否可用。false不能用 true能用
<%@page session="true" %>
3-errorPage和isErrorPage:
errorPage 指定当前页面出现错误实际响应页面是什么? 其中的/表示当前WEB应用的根目录(不加也是)
<%@ page errorPage="error.jsp" %> (还可以在web.xml中配置
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.html</location>
</error-page>
<error-page>
<!--制定异常类型-->
<exception-type>java.lang.ArithmeticException</exception-type>
<!--指定响应页面的位置-->
<location>/WEB-INF/error.jsp</location>
</error-page>
)
isErrorPage:指示当前页面是否为错误处理页面,同时也表示是否可以用exception内置对象
若指定isErrorPage = "true",并使用exception的方法,一般不建议直接访问该错误页面。
如何使客户不能直接访问某一个页面?对于Tomcat服务器而言,WEB-INF下的文件是不能通过在浏览器中直接输入
来访问的。但通过请求转发是可以的。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="WEB-INF/error.jsp" %> (这其实也使请求转发的方式)
或者Servlet中request.getRequestDispatcher("WEB-INF/error.jsp").forward(request, response);
需要用请求转发<%@ page errorPage="error.jsp" %> 转到error.jsp的错误页面
4-contentType
contentType:指定当前jsp页面的响应类型
实际使用的是response.setContentType("text/html; charset=UTF-8");
通常情况下对于jsp页面而言取值均为 text/html
5-charset
charset:指定返回的页面的字符编码 通常取值为utf-8
6-pageEncoding
pageEncoding:指定当前jsp页面的字符编码 通常与charset一致
7-isELIgnore :指定当前jsp页面是否可以使用EL表达式 。 通常值为true
4.include指令
1)通知jsp引擎在翻译当前jsp页面时将其他文件中的内容合并进当前jsp页面转化为Servlet源文件中 (至始至终只有1个Servlet源文件)
这种在源文件级别进行引入的方式称之为静态引入,当前jsp页面与静态引入的页面紧密合成一个Servlet。
2)file属性的设置必须使用相对路径
3)如果以"/"开头,表示在当前WEB应用程序的根目录(注意不是WEB站点目录)。
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>AAA PAGE</h3>
<%
String h = "sdf";
%>
<!-- 在a.jsp中包含b.jsp -->
<%@include file="b.jsp" %>
</body>
</html>
JSP标签
1=jsp:include标签
1)动态引入:<jsp:include page="b.jsp"></jsp:include>
并不是像inlcude指令生成一个Servlet源文件,而是生成了2个Servlet源文件看(D:\software\apache-tomcat-8.0.52\work\Catalina\localhost\jsp\org\apache\jsp\include2)
然后通过一个方法(org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "b.jsp", out, false);)报目标页面包含进去
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>AAA PAGE</h3>
<%
String h = "sdf";
%>
<!-- 在a.jsp中包含b.jsp -->
<jsp:include page="b.jsp"></jsp:include>
</body>
</html>
b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>BBB PAGE</h3>
<%= h %>
</body>
</html>
/*
会出错想想为啥 (是因为有2个个Servlet源文件 在 a_jsp.java声明了h变量 而在b_jsp.java中并不知道h这个)
*/
2)<jsp:include>标签和include指令
<jsp:include>标签 2个Servlet源文件
include指令 1个Servlet源文件
2=jsp:forword
1)<jsp:forward>:相当于请求转发的代码
<jsp:forward page="/include3/b.jsp"></jsp:forward>
2)但使用jsp:forward可以使用jsp:param子标签向b.jsp传入一些参数。同样<jsp:include>标签也可以
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>AAA PAGE</h3>
<!-- 1 -->
<jsp:forward page="/include4/b.jsp">
<jsp:param value="asd" name="kkk"/>
</jsp:forward>
<!-- 2 -->
<jsp:include page="/include4/b.jsp">
<jsp:param value="asd" name="kkk"/>
</jsp:include>
</body>
</html>
b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>BBB PAGE</h3>
<%= request.getParameter("kkk")%>
</body>
</html>
<jsp:forward> <jsp:include>
/*
AAA PAGE
BBB PAGE
/* asd
BBB PAGE */
asd
*/
关于中文乱码
1)在jsp页面上输入中文,请求页面后不会出现乱码
保证<%@Page charset=UTF-8" pageEncoding="UTF-8">这个条件还需要保证浏览器的字符编码和Jsp页面的编码一致
2)保证中文参数值一致:默认参数在传输过程中使用的编码为ISO-8859-1
a.jsp
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="WEB-INF/error.jsp" %>
<%@page session="true" %>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="kk.jsp" method="post">
<input type="text" name="name">
<input type="submit" value="sss"/>
</form>
</body>
</html>
kk.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8";
pageEncoding="UTF-8"%>
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Java 你好
<%
request.setCharacterEncoding("UTF-8");
%>
user : <%=request.getParameter("name") %>
</body>
</html>
1-对于post请求只要在获取请求信息之前调用
<%
request.setCharacterEncoding("UTF-8");
%>就可以了
2-对于get请求:(request.setCharacterEncoding("UTF-8");)可能对get无效
查看http://localhost:8080/docs/config/http.html 里面的useBodyEncodingForURI方法
我们可以通过修改tomcat的servlet.xml文件的方式进行修改
(2处servlet.xml文件需要修改
一处:D:\software\apache-tomcat-8.0.52\conf
二处:在eclipse中的Servers
)
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443">加入useBodyEncodingForURI="true"为
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>