Java Servlet学习笔记——3.URL重写

写在前面

继续学习Java Servlet,这一部分学习URL重写,虽然这些技术用的不多,而且代码也比较简单,但是我还是决定一节一节的记录。仔细看看示例代码还是有很多内容。

URL重写

URL重写是一种会话跟踪技术, 它将一个或多个token添加到URL的查询字符串中, 每个token通常为key=value形式, 如下:

url?key-1=value-1&key-2=value-2 ... &key-n=value-n

注意, URL和tokens间用问号(? ) 分割, token间用与号(&) 。

URL重写适合于tokens无须在太多URL间传递的情况下, 然而它有如下限制:

  • URL在某些浏览器上最大长度为2000字符;
  • 若要传递值到下一个资源, 需要将值插入到链接中, 换句话说, 静态页面很难传值;
  • URL重写需要在服务端上完成, 所有的链接都必须带值, 因此当一个页面存在很多链接时, 处理过程会是一个不小的挑战;
  • 某些字符, 例如空格、 与和问号等必须用base64编码;
  • 所有的信息都是可见的, 某些情况下不合适。

因为存在如上限制, URL重写仅适合于信息仅在少量页面间传递, 且信息本身不敏感。

示例代码

下面将构造一个Top10Servlet类会显示最受游客青睐的10个伦敦和巴黎的景点。 信息分成两页展示, 第一页展示指定城市的5个景点, 第二页展示另外5个。 该Servlet使用URL重写来记录所选择的城市和页数。 该类扩展自HttpServlet, 并通过/top10访问。

package app02a.urlrewriting;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "Top10Servlet", urlPatterns = { "/top10" })
public class Top10Servlet extends HttpServlet {
    private static final long serialVersionUID = 987654321L;
    private List<String> londonAttractions;
    private List<String> parisAttractions;

    @Override
    public void init() throws ServletException {

        londonAttractions = new ArrayList<String>(10);
        londonAttractions.add("Buckingham Palace");
        londonAttractions.add("London Eye");
        londonAttractions.add("British Museum");
        londonAttractions.add("National Gallery");
        londonAttractions.add("Big Ben");
        londonAttractions.add("Tower of London");
        londonAttractions.add("Natural History Museum");
        londonAttractions.add("Canary Wharf");
        londonAttractions.add("2012 Olympic Park");
        londonAttractions.add("St Paul's Cathedral");

        parisAttractions = new ArrayList<String>(10);

        parisAttractions.add("Eiffel Tower");
        parisAttractions.add("Notre Dame");
        parisAttractions.add("The Louvre");
        parisAttractions.add("Champs Elysees");
        parisAttractions.add("Arc de Triomphe");
        parisAttractions.add("Sainte Chapelle Church");
        parisAttractions.add("Les Invalides");
        parisAttractions.add("Musee d'Orsay");
        parisAttractions.add("Montmarte");
        parisAttractions.add("Sacre Couer Basilica");
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String city = request.getParameter("city");
        if (city != null && (city.equals("london") || city.equals("paris"))) {
            // show attractions
            showAttractions(request, response, city);
        } else {
            // show main page
            showMainPage(request, response);
        }
    }

    private void showMainPage(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException,IOException {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print("<html><head>" +
                    "<title>Top 10 Tourist Attractions</title>" +
                    "</head><body>" +
                    "Please select a city:" +
                    "<br/><a href='?city=london'>London</a>" +
                    "<br/><a href='?city=paris'>Paris</a>" +
                    "</body></html>");
    }

    private void showAttractions(HttpServletRequest request, HttpServletResponse response, String city)
            throws ServletException, IOException {
        int page = 1;
        String pageParameter = request.getParameter("page");
        if (pageParameter != null) {
        try {
            page = Integer.parseInt(pageParameter);
        } catch (NumberFormatException e) {
            // do nothing and retain default value for page
        }
            if (page > 2) {
                page = 1;
            }
        }
        List<String> attractions = null;
        if (city.equals("london")) {
            attractions = londonAttractions;
        } else if (city.equals("paris")) {
            attractions = parisAttractions;
        }
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.println("<html><head>" +
                    "<title>Top 10 Tourist Attractions</title>" +
                    "</head><body>");
        writer.println("<a href='top10'>Select City</a> ");
        writer.println("<hr/>Page " + page + "<hr/>");
        int start = page * 5 - 5;
        for (int i = start; i < start + 5; i++) {
            writer.println(attractions.get(i) + "<br/>");
        }
        writer.print("<hr style='color:blue'/>" +
                    "<a href='?city=" + city +
                    "&page=1'>Page 1</a>");
        writer.println("&nbsp; <a href='?city=" + city +
                    "&page=2'>Page 2</a>");
        writer.println("</body></html>");
        }
}

函数功能说明

1.init()函数。仅当该servlet第一次被用户访问时调用,构造两个类级别的列表, londonAttractions和
parisAttractions, 每个列表有10个景点。

2.doGet()函数。该方法每次请求时被调用, 检查URL中是否包括请求参数city, 并且其值是否为“london”或“paris”, 方法据此决定是调用showAttractions方法还是showMainPage方法。

3.showMainPage()函数。向浏览器发送主页面,提供两个链接选择,一个链接显示城市London,另一个链接显示城市Paris。

4.showAttractions()函数。向浏览器发送展示城市景点的页面。

程序运行过程说明

通过URL调用Servlet之后,首先由于该servlet第一次被用户访问,会调用init()函数。

由于用户一开始访问该servlet时不带任何请求参数, 此时调用showMainPage, 该方法发送两个链接到浏览器, 每个链接都包含token: city=cityName:

"Please select a city:" +
"<br/><a href='?city=london'>London</a>" +
"<br/><a href='?city=paris'>Paris</a>" +

请注意a元素中的href属性, 该属性值包括一个问号加token city=london或city=paris. 注意, 此处为相对URL, 即URL中没有协议部分, 相对于当前页面。 因此, 若你点击了任一链接, 则会提交:

http://localhost:8080/app02a/top10?city=london

http://localhost:8080/app02a/top10?city=paris

到服务器上。

用户点击两个链接中的一个之后,就会向Servlet发送请求,会调用doGet()函数,而该函数会识别请求参数的city值并传递给showAttractions方法, 该方法会检查URL中是否包含page参数, 如果没有该参数或该参数值无法转换为数字, 则该方法设定page参数值为1, 并将头5个景点发给客户端。

showAttractions方法还发送了3个链接到客户端:Select City、 Page 1和Page 2。 Select City 是无参数访问servlet, Page 1和Page 2链接包括两个tokens, 即city和page:

http://localhost:8080/app02a/top10?city=cityName&page=pageNumber

若选择了伦敦, 并点击了Page 2, 则将以下URL发送给服务端:

http://localhost:8080/app02a/top10?city=london&page=2

写在后面

不同页面之间的跳转我一直很好奇,但通过这个程序发现这个程序就是通过发送href来实现不同页面的跳转的。先记录这么多。

猜你喜欢

转载自blog.csdn.net/zy2317878/article/details/80241410