前言
html ,js 可以实现页面跳转。
jsp , asp, php 也有各自页面跳转与重定向的方式。
下文针对js 和jsp 的页面跳转实现方式进行一个总结。
html 页面跳转方式
可以使用html 的meta 标签实现页面的跳转。
<!--Add by oscar999--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Author" CONTENT="oscar999"> <meta http-equiv="refresh" content="0; URL=http://www.csdn.net"> <script> </script> </HEAD> <BODY> This is Test Page </BODY> </HTML>
这种用法比较常使用在:
新旧系统升级的状况下, 暂时保留旧系统,通过域名进入时自动转到新系统中。
JS 页面跳转方式
1. 使用window.location = "newurl"
<!--Add by oscar999--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Author" CONTENT="oscar999"> </HEAD> <BODY> This is Test Page. <script> window.location="http://www.csdn.net"; </script> </BODY> </HTML>
也可以使用 window.location.href = "http://www.csdn.net";
2. 使用 window.navigate
<script> window.navigate("http://www.csdn.net"); </script>
3. window.loction.replace方式实现页面跳转
<script language="javascript"> window.location.replace("target.aspx"); </script>
有3个jsp页面(1.aspx, 2.aspx, 3.aspx),进系统默认的是1.aspx,当我进入2.aspx的时候, 2.aspx里面用window.location.replace("3.aspx");
与用window.location.href ("3.aspx");
从用户界面来看是没有什么区别的,但是当3.aspx页面有一个"返回"按钮,调用window.history.go(-1); wondow.history.back();方法的时候,一点这个返回按钮就要返回2.aspx页面的话,区别就出来了,当用 window.location.replace("3.aspx");连到3.aspx页面的话,3.aspx页面中的调用 window.history.go(-1);wondow.history.back();方法是不好用的,会返回到1.aspx。
JSP跳转方式
JSP 跳转方式大约有三种:
1. response.sendRedirect(“newurl”);
-- 此语句前不允许有out.flush(),如果有,会有异常:
java.lang.IllegalStateException: Can't sendRedirect() after data has committed to the client.
at com.caucho.server.connection.AbstractHttpResponse.sendRedirect(AbstractHttpResponse.java:558)
--跳转后浏览器地址栏变化
--如果要跳到不同主机下,跳转后,此语句后面的语句会继续执行,如同新开了线程,但是对response的操作已经无意义了
如果要跳到相同主机下,此语句后面的语句执行完成后才会跳转;
2. response.setHeader("Location","newurl");
response.setStatus(302);
response.setHeader("location","newurl");
这种使用方式要结合 setStatus(302), 302 这个状态码就是告诉浏览器要重定向了。
- 此语句前不允许有out.flush(),如果有,页面不会跳转。
- 跳转后浏览器地址栏变化
- 此语句后面的语句执行完成后才会跳转
3. <jsp:forward page="newurl" />
此语句前不允许有out.flush(),如果有,会有异常:
跳转后浏览器地址栏不变,但是只能跳到当前主机下
此语句后面的语句执行完成后才会跳转
跳转后得路径变为当前路径,图片不是绝对路径将无法显示
例子:
整个简单的例子: 两个文件 a.jsp 和 b.jsp .
<!-- by oscar999 --> <!-- This is a.jsp --> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> Before: This is a.jsp! <br> <% //response.sendRedirect("b.jsp"); //response.setStatus(302); //response.setHeader("location","b.jsp"); %> <jsp:forward page="b.jsp"/> After: This is a.jsp! </body> </html>
对于jsp 而言, 就需要嚼一嚼Redirect 和 forward 的差别了。
就字面意思而已: Redirect 翻译成重定向, forward翻译成转发。
两者的区别是:
重定向是客户端行为,转发是服务器行为
重定向过程:客户浏览器发送http请求——》web服务器接受后发送302状态码响应及对应新的location给客户浏览器——》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址——》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
转发过程:客户浏览器发送http请求——》web服务器接受此请求——》调用内部的一个方法在容器内部完成请求处理和转发动作——》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
类别
|
概念
|
共享数据
|
应用
|
Redirect
|
URL重新定向:可以是任意的URL
|
不能共享request里面的数据
|
一般用于用户注销登录时返回主页面和跳转到其它的网站等等
|
Forward
|
页面的转发:只能是同一个Web应用程序的其他Web组件
|
转发页面和转发到的页面可以共性request里面的数据
|
一般用于用户登录的时候根据角色转发到相应的模块等等
|
有个例子说明两者的区别很生动:
假设你去办理某个执照
重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。
转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。
以上基本是在页面层级进行页面的跳转, 进入一个页面后跳入另一个页面;
下面从项目和服务端来看看有可能在实际的项目中使用到的状况:
旧的地址跳转到新的地址
在系统开发过程中, 新旧系统并存是一种常见的处理方法,新旧系统有着各自独立的域名地址。 、
当新系统开发完成的时候,就需要把旧地址的域名导到新地址中了。
方法之一 就是进行DNS 修改映射了。
如果系统没有域名, 只有IP, 或是不想修改DNS 的话, 就可以在旧系统中修改主页面。最简单的就是类似:
<TITLE>New System</TITLE> <META name="description" content="New System Forward"> <META name="keywords" content="New System"> <META name="robots" content="index,follow,all"> <meta http-equiv="refresh" content="0; URL=http://newurl">
Tomcat 中的地址设定
Tomcat 默认安装的状况下(port:8080), 项目部署在webapps 目录下。
举例: 这里的域名myweb ,这里的项目名 myproject ,
本地的访问地址就是 : http://IP:8080/myproject.
域名映射后地址就是: http://myweb:8080/myproject
1. 如何去除端口?
方法一: 在安装是设置成 80 端口
方法二: 如果已经安装完成, 可以修改conf\server.xml 的下面配置
修改成 80 就可以了。
这样就可以通过以下方式访问了:
http://myweb/myproject
2. 如何去除项目名称。
最方便的访问方式应该就是直接输入 域名就进入了。
http://myweb
方法一: 修改 conf\server.xml 配置
在host 中添加如下Context 的配置:
方法二: 如果不使用方法一的话, 默认状况上面的地址, 会进入 webapps\ROOT\index.html 这个文件。
所以使用以上的方法修改这个页面的跳转应该就能达到所需要的效果了。
二级域名的重定向
新系统虽然已开发完成, 但是还是想有些旧的模块功能使用旧的系统。
这样的话, 访问新系统的某些url 的时候,重定向到旧的页面地址中去。
以访问 http://myweb/old 的方式访问旧的地址(比如旧的地址就是http://www.csdn.net)
方法一: 增加 filter
步骤一: 新增 Filter 的java 文件, 文件名 UrlRewriteFilter.java, 内容如下
package com.oscar999; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** <description> * * @see * @see * * @version 0.1, 2014-5-29 * @author oscar999 * @since JDK1.5 */ public class UrlRewriteFilter implements Filter{ @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String requestPath = httpRequest.getRequestURI(); if(requestPath.indexOf("/old")>0) { //request.getRequestDispatcher("/redirect.html").forward(request, response); httpResponse.sendRedirect("http://www.csdn.net"); return; } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
步骤二: 在web.xml 中 添加filter 的定义
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>com.oscar999.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/old</url-pattern> </filter-mapping>
说明:
1. 在Java 中,满足转向的状况, 一定要return 。 否则会报 IllegalStateException错误
2. 可以比较一下, forward 和 redirect 的使用差别 ?
1) 调用的对象不同(request , response)
2) 使用的场景不同(是否是本项目中的文件)
3) url 的地址的变化
3. 转向的逻辑的可以通过init-param 配置在filter 的 xml 中
<init-param> <param-name></param-name> <param-value></param-value> </init-param>
在filter 的init方法 中,通过 Enumeration<?> e = filterConfig.getInitParameterNames(); 读到。
这样的话, 就可以灵活配置转向的逻辑了。
方法二: 直接使用 urlwrite 组件
其实上面的方式, 已经有共用的组件可以用了。
组件的介绍地址 :
http://tuckey.org/urlrewrite/
目前最新版的下载地址:
http://urlrewritefilter.googlecode.com/files/urlrewritefilter-4.0.3.jar
也可以到:
下载
有了方法一的介绍, 这个组件的使用就很容易了。
1. 下载jar , 放入项目路径中
2. 配置 web.xml
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3. 在web.xml 的同路径下,添加 urlrewrite.xml 文件, 内容如下:
<?xml version="1.0" encoding="UTF-8"?> <urlrewrite> <rule> <from>/old</from> <to type="redirect">http://www.csdn.net</to> </rule> </urlrewrite>
这里可以配置很多的转向逻辑,不过有上下层级关系时,也就是既有二级域名又有三级域名的话, 配置起来会有一些问题。
不难理解三级在二级的基础上又换了一次, 导致url 会不对。
另外, 如果项目使用的是 http://myweb/myproject 这种通过项目名访问的话,
映射旧的地址可以在 tomcat/webapps 中放入一个旧项目同名的项目,里面没什么内容,专门用来做重定向。