一:Web之间跳转和信息共享
01.为什么需要Servlet之间的交互
Web组件(Servlet/JSP)的交互:
Web组件之间的跳转,数据共享.
为什么Web组件之间需要跳转,需要数据共享.
web组件跟JSP交互的示意图
02.请求转发
请求转发:
从Servlet1,请求转发到Servlet2.
Servlet1完成一部分的功能,再跳转到Servlet2,继续完成剩下的功能.
语法:
request.getRequestDispatcher(String path).forward(request,response);
参数:path,表示跳转的目标路径(资源名称).
注意:别忘了forward.
分析请求转发的特点:
1:浏览器地址栏不发生改变,依然是/forward/s1,不是目标地址(/forward/s2).
2:请求转发只发送一个请求.
3:共享同一个请求中的数据.
4:最终响应给浏览器的由Servlet2来决定.
5:请求转发不能跨域访问,只能跳转到当前应用中的资源.
6:请求转发可以访问WEB-INF目录中的资源.
请求转发特点分析图
03.URL重定向
URL重定向:
语法:
response.sendRedirect(String url);
参数:url,表示目标资源地址
分析URL重定向的特点:
1:浏览器地址栏发生变化,从/redirect/s1,变成目标地址(/redirect/s2).
2:URL重定向发了两次请求.
3:因为URL重定向是两次独立的请求,所以不共享请求中的数据.
4:最终响应给浏览器的由Servlet2来决定(把目标地址拷贝到浏览器地址栏,敲回车)
5:URL重定向能跨域访问,可以访问其他应用中的资源.
6:URL重定向不能访问WEB-INF目录中的资源.
URL重定向请求分析图
04.请求包含和forward以及redirect的选择
请求包含:
在一个页面中可以包含其他页面的内容.
在Servlet中没意义,在JSP中有意义.
语法:
request.getRequestDispatcher(String path).include(req,resp);
请求转发和URL重定向都支持Web组件之间的跳转,如何选择?
分析各自的特点.
必须使用请求转发(forward);
1):如果需要共享请求中的数据.
2):如果需要访问WEB-INF中的资源.
如果需要跨域访问,避免表单的重复提交,只能使用URL重定向.
其他情况,任选.
二:Servlet的三大作用域对象
05.Servlet的三大作用域对象:
目的:共享数据
request: 每一次请求都是一个新的request对象,如果在web组件之间需要共享同一个请求中的数据,只能使用请求转发.
session: 每一次会话都是一个新的session对象,如果如果需要在一次会话中的多个请求之间需要共享数据,只能使用session.
application: 应用对象,Tomcat启动到Tomcat关闭,表示一个应用,在一个应用中有且只有一个application对象,作用于整个
Web应用,可以实现多次会话之间的数据共享.
对象名称: 对象类型:
request HttpServletRequest
session HttpSession
servletcontext(application) ServletContext
作用域对象如何共享数据:
1:设置作用域中的共享数据.
作用域对象.setAttribute(String name , Object value);
2:获取作用域中的共享数据.
Object value = 作用域对象.getAttribute(String name);
3:删除作用域中的指定的共享数据.
作用域对象.removeAttribute(String name);
注意:在哪一个作用域中设置共享数据,就只能从该作用域中取出数据.
三大作用域的示意图
06.三大作用域对象案例
//从/scope资源转到/result资源,并共享数据.
@WebServlet("/scope")
public class ScopeServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//request:
Integer numInRequest = (Integer) req.getAttribute("NUM_IN_REQUEST");
if(numInRequest==null){
req.setAttribute("NUM_IN_REQUEST", 1);
}else{
req.setAttribute("NUM_IN_REQUEST", numInRequest+1);
}
//==================================
//session:
Integer numInSession = (Integer) req.getSession().getAttribute("NUM_IN_SESSION");
if(numInSession == null){
req.getSession().setAttribute("NUM_IN_SESSION", 1);
}else{
req.getSession().setAttribute("NUM_IN_SESSION", numInSession + 1);
}
//==================================
//application:
Integer numInApp = (Integer) req.getServletContext().getAttribute("NUM_IN_APP");
if(numInApp==null){
req.getServletContext().setAttribute("NUM_IN_APP", 1);
}else{
req.getServletContext().setAttribute("NUM_IN_APP",numInApp+1);
}
//==================================
req.getRequestDispatcher("/result").forward(req, resp);
}
}
@WebServlet("/result")
public class ResultServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//============================
out.print("request="+req.getAttribute("NUM_IN_REQUEST"));
out.print("</br>session="+req.getSession().getAttribute("NUM_IN_SESSION"));
out.print("</br>application="+req.getServletContext().getAttribute("NUM_IN_APP"));
}
}
07.ServletContext接口和常用方法
ServletContext接口:表示Web应用对象,(从Tomcat启动到Tomcat关闭之间,应用中有且只有一个ServletContext对象,
而且是在Tomcat启动的时候就创建的 ,所以在JSP中把对象称为:application)
如何获取ServletContext对象:
方式1:在Servlet类中:super.getServletContext();
方式2:通过请求对象来获取:request.getServletContext();该方法是从Tomcat7开始存在的.
方式3:通过session对象来获取:request.getSession().getServletContext();
注意:无论是哪一种方式,获取的都是同一个ServletContext对象.
常用的方法:
1:String getRealPath(String path):根据一个资源的相对Web根的路径,获取它的绝对路径.
String realPath = super.getServletContext().getRealPath("/WEB-INF/in.html");
2:String getContextPath();返回当前应用的上下文路径<Context path="XXXX"/>;
如果多个Web组件之间有相同的初始化参数配置,此时配置重复怎么解决?-->全局初始化参数.
获取全局的初始化参数,只能使用以下的俩个方法:
String getInitParameter(String name);获取指定名称的全局初始化参数.
Enumeration<String> getInitParameterNames();获取所有全局的初始化参数的名字.
注意:
ServletConfig接口中的获取初始化参数的方法,只能获取当前Servlet自身的初始化参数,不能获取全局的初始化参数.
ServletContext接口中的获取初始化参数的方法,只能获取全局的初始化参数,不能获取局部的初始化参数.
三 : 动态网页JSP
08.动态网页
Java中的动态网页:
Servlet动态网页 = Java代码(主) + HTML(辅):(在Servlet中编写html代码)
JSP动态网页 = Java代码(辅) + HTML代码(主):(在html中编写java代码)
Servlet不擅长是界面输出,JSP最擅长界面输出.
Servlet擅长的事情:
1):接受请求参数,封装成对象.
2):调用业务方法,来处理请求.
3):控制界面跳转,跳转到某一个JSP负责做界面输出操作.
责任分离思想:各自做各自最擅长的事情.
09.JSP的原理和第一个程序
JSP(Java Servlet Page):Java的服页面,Java动态页面.
JSP的本质就是Servlet.
Tomcat中目录下的web.xml文件:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name> //servlet的通配符映射
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
从上图的配置文件,发现JspServlet的通配符映射为:*.jsp 说明在浏览器的地址栏中所有以.jsp的资源都会交给JspServelt的类来处理.
问题:JspServlet到底把资源做什么处理了?
Tomcat把所有以.jsp结尾的资源都交给JSPServlet来做处理.
hello.jsp ---> hello_jsp.java ---> hello_jsp.class
public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
out.write("<title>Insert title here</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\t\t北京时间:");
out.print(new java.util.Date().toLocaleString() );
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
}
}
而HttpJspBase又继承于HttpServlet这个类
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
//这是HttpJspBase中的方法.
public void _jspInit() {
}
protected void _jspDestroy() {
}
public abstract void _jspService(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
10.JSP的基本语法
1:JSP的注释:
作用:注释Java脚本代码
语法:<%--这是注释-->
2:JSP的Java脚本表达式:
作用:输出数据到页面上
语法:<%=表达式%>(实际上就是调用输出流打印到页面上)out.print(表达式):
3:JSP中的Java脚本片段(实际开发中,应做到JSP中不能出现一行Javaj脚本片段)
作用:书写Java代码逻辑
语法:<% 语句1,语句2 %>
原理:其中的语句会原封不动的被服务器翻译到对应的Servelt的_jspService方法中.
4:JSP的声明
作用:定义类的成员
语法:<%! Java代码 %>
原理:其中的语句会原封不动的被服务器翻译到对应的Servlet类中,作为成员变量和方法.
JSP的基本语法示意图
11.page指令
JSP的标准指令:设定JSP网页的整体配置信息.
特点: 1:并不向客户端产生任何输出
2:指令在JSP整个文件范围内有效
3:为翻译阶段提供了全局信息.
每一个JSP都得有page指令,一般放在JSP的第一行.
JSP的三大指令:
1):page: 在Java中编写指令的语法: <%@ 指令名称 属性="属性值"... %>
2):include
3):taglib
Page指令:表示的JSP页面相关的配置信息
常用属性:
language:表示的JSP中编写的脚本的语言.
contentType:表示JSP输出的MIME类型和编码.
等价于 response.setContentType("text/html; charset=UTF-8");
pageEncoding:表示JSP输出的编码.
response.setCharacterEncoding("UTF-8");
若contentType和pageEncoding共存,以pageEncoding为主.
import:用于导入JSP脚本中使用到的类,等价于java代码中的import 类的全限定名;
isErrorPage:是否把当前页面设置专门显示错误的页面.页面内容如下:
属性值要设置为:isErrorPage="true"
<% String msg = exception.getMessage(); %>
出现信息:<%=msg %>
Errorpage:当前页面出错之后,需要跳转到哪一个页面上去.
属性值设置为:errorPage="errorpage.jsp" 它为上面的页面
12.异常页面处理
上面有配置错误页面的属性,下面这是配置全局页面的属性,先找page里面的属性错误跳转,找不到再找全局页面属性错误跳转.
配置全局错误提示页面:web.xml中
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location> //表示输错URL的错误提示
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location> //表示代码写错的提示信息
</error-page>
13.JSP的九大内置对象和四大作用域
JSP的九大内置对象: 在JSP中不需要声明和定义,可以直接使用的对象.
内置对象名称 内置对象类型 描述
----------------------------------------------------------------------------------------------------
request HttpServletRequest 请求对象
response HttpServeltResponse 响应对象
pageContext PageContext 当前JSP作用域对象
session HttpSession 会话对象(page指令:session="true")
exception Throwable 异常类型,封装了当前JSP的异常信息(isErrorPage="true")
application ServletContext 当前Web应用对象
config ServletConfig 当前Servelt的信息配置对象
out JspWriter 字符输出流对象
page Object 当前Servlet对象
JSP的四大作用域: 作用域对象只能在自己作用范围之内共享数据.
作用域对象名称 作用域对象的类型 描述
---------------------------------------------------------------------------------------------------------
pageContext(page) pageContext 当前JSP作用域对象
request HttpServletRequest 当前请求的作用域
session HttpSession 当前会话的作用域
application ServletContext 当前Web应用的作用域
14.静态和动态包含
JSP的动作元素:
<jsp:forward>: 请求转发的标签
<jsp:param/>: 在包含和转发时,利用该标签传递请求参数
静态和动态包含:
静态包含: 使用JSP的include指令: <%@ include file="被包含的页面文件" %>
特点: 在翻译阶段就已经把多个JSP,合并在一起.
动态包含: 使用JSP的动态指令: <jsp:include page="被包含的页面文件"/>
特点: 把每一个JSP都翻译成Servelt类,在运行时期,动态的合并在一起.
什么时候使用静态包含,什么时候使用动态包含?
如果在包含的时候,需要传递数据,此时只能使用动态包含.
<jsp:include page="top.jsp">
<jsp:param value="" name=""/>
</jsp:include>
15.Servlet和JSP的综合案例
这里写代码片
今天关于JavaWeb的面试题:
1):请求转发和URL重定向的区别.
2):forward和redirect的区别(和1一样).
3):说说什么是JSP
4):说说JSP的三大指令是什么,分别有什么用.
5):说说JSP的九大内置对象.
6):说收JSP的四大作用域对象.
7):说说静态包含和动态包含的区别.