杰瑞科技汇

JavaJava中如何实现URL重写?

Of course! "URL Rewriting" in Java can refer to two main things, which are often confused but serve different purposes:

JavaJava中如何实现URL重写?-图1
(图片来源网络,侵删)
  1. Client-Side URL Rewriting (The Classic, Older Technique): This is a mechanism used by web servers and applications to maintain a user's session without relying on cookies. It involves embedding a session ID directly into the URLs of hyperlinks.
  2. Server-Side URL Rewriting (The Modern, Recommended Technique): This is a powerful technique for creating clean, user-friendly, and SEO-friendly URLs. It's about mapping a public URL (e.g., /products/laptop-123) to an internal resource (e.g., /products.jsp?id=123) without the user or search engine ever seeing the internal URL. This is what most people mean today when they talk about URL rewriting.

Let's break down both, with a strong focus on the modern, server-side approach.


Client-Side URL Rewriting (For Session Management)

This technique was primarily used when users disabled cookies in their browsers, which would break the default session management in Java web applications (like Servlets and JSP).

How it Works:

When a server needs to send a link to a JSP page, it appends the session ID to the URL. The browser then sends this ID back with every subsequent request, allowing the server to re-associate the request with the correct session.

Example in a JSP:

Let's say a user's session ID is ABC123XYZ. A normal link would look like this:

JavaJava中如何实现URL重写?-图2
(图片来源网络,侵删)
<a href="welcome.jsp">Go to Welcome Page</a>

With URL rewriting, the server (JSP engine) automatically modifies it to:

<a href="welcome.jsp;jsessionid=ABC123XYZ">Go to Welcome Page</a>

(Note: The format can vary, e.g., welcome.jsp?jsessionid=ABC123XYZ or using a path parameter like welcome.jsp;jsessionid=ABC123XYZ)

How to Enable/Use It:

You don't have to do the rewriting manually. The JSP container (like Tomcat) does it for you automatically if you use special JSP tags.

Good Practice (Using JSTL):

JavaJava中如何实现URL重写?-图3
(图片来源网络,侵删)
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<!-- The c:url tag will automatically rewrite the URL if cookies are disabled -->
<a href="<c:url value='/welcome.jsp' />">Go to Welcome Page</a>

Older Way (Using JSP Action Tags):

<a href="<%= response.encodeURL("welcome.jsp") %>">Go to Welcome Page</a>

In a Servlet:

String url = "/welcome.jsp";
// encodeURL() checks if cookies are supported. If not, it rewrites the URL.
String rewrittenUrl = response.encodeURL(url);
response.sendRedirect(rewrittenUrl);

Conclusion on Client-Side Rewriting: This is largely a legacy technique. Modern browsers almost always have cookies enabled, so this is no longer a common concern. The focus has shifted to server-side rewriting for better user experience and SEO.


Server-Side URL Rewriting (The Modern Approach)

This is about creating a clean, public-facing URL structure and mapping it to an internal application resource. This is crucial for:

  • User Experience: /products/laptop-123 is much nicer than /products.jsp?id=123&category=electronics.
  • SEO: Search engines prefer clean, descriptive URLs.
  • Maintainability: You can change your internal URL structure (e.g., from .jsp to .do or a REST endpoint) without breaking all your external links and bookmarks.

There are two primary ways to achieve this in a Java web application:

A. Using a Framework (Recommended)

Modern web frameworks handle URL routing and rewriting out of the box. They use an annotation-based approach which is clean and declarative.

Example with Spring Boot:

This is the most common and straightforward method in modern Java development.

  1. Define a Controller: You map a clean URL path to a Java method that handles the request.

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.ui.Model;
    @Controller
    public class ProductController {
        // Maps a GET request for "/products/{id}" to this method
        // The {id} is a path variable.
        @GetMapping("/products/{id}")
        public String showProduct(@PathVariable("id") String productId, Model model) {
            // In a real app, you would fetch the product from a database
            // using the productId.
            System.out.println("Fetching product with ID: " + productId);
            // Add product data to the model to be used in the view
            model.addAttribute("productId", productId);
            model.addAttribute("productName", "Super Laptop " + productId);
            // Return the name of the JSP/HTML template to render
            return "product-details"; // This resolves to /WEB-INF/views/product-details.jsp
        }
    }
  2. How it Works:

    • A user requests http://yourapp.com/products/laptop-123.
    • The Spring DispatcherServlet receives this request.
    • It looks for a @Controller with a @GetMapping mapping that matches /products/{id}.
    • It extracts laptop-123 as the value for the id path variable.
    • It calls the showProduct method, passing laptop-123 as the productId argument.
    • The method processes the request and returns the view name product-details.
    • Spring renders the product-details.jsp page, making the product data available.

This is not "rewriting" in the traditional sense (like an Apache mod_rewrite rule), but rather routing. The effect is the same: a clean URL is mapped to an internal handler.

B. Using a Filter (For Legacy Servlet Apps)

If you are not using a framework like Spring, you can achieve URL rewriting with a Servlet Filter. This is more manual and requires you to configure the filter in your web.xml.

Example with a Tuckey URLRewriteFilter: The Tuckey URLRewriteFilter is a very popular and powerful open-source library for this purpose.

  1. Add the Dependency: Add the JAR to your WEB-INF/lib directory or include it in your build tool (Maven/Gradle).

    <!-- Maven Dependency -->
    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>4.0.4</version>
    </dependency>
  2. Configure the Filter in 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. Create the urlrewrite.xml Configuration File: Place this file in your WEB-INF directory. This is where you define your rewriting rules.

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
        "http://tuckey.org/res/dtds/urlrewrite4.0.dtd">
    <urlrewrite>
        <rule>
            <from>^/products/([a-zA-Z0-9-]+)$</from>
            <to type="forward">/products.jsp?id=$1</to>
        </rule>
        <!-- Another example for a blog post -->
        <rule>
            <from>^/blog/(\d{4})/(\d{2})/([a-zA-Z0-9-]+)$</from>
            <to type="forward">/blog-post.jsp?year=$1&month=$2&slug=$3</to>
        </rule>
        <!-- Rule to redirect an old URL to a new one (SEO) -->
        <rule>
            <from>^/old-page\.html$</from>
            <to type="redirect">/new-page.html</to>
        </rule>
    </urlrewrite>

Explanation of the Rule:

  • <from>^/products/([a-zA-Z0-9-]+)$</from>: This is a regular expression that matches any URL starting with /products/ followed by one or more letters, numbers, or hyphens. The parentheses create a capturing group.
  • <to type="forward">/products.jsp?id=$1</to>: This is the target URL. $1 is a back-reference to the first capturing group from the <from> pattern. type="forward" means the request is forwarded internally to the JSP. The user's browser URL in the address bar will remain /products/laptop-123.
  • type="redirect": This would send an HTTP 301 or 302 redirect to the browser, causing the URL in the address bar to change. This is useful for permanent moves.

Summary and Recommendation

Feature Client-Side Rewriting (Session) Server-Side Rewriting (Routing)
Purpose Maintain sessions when cookies are disabled. Create clean, user-friendly, and SEO-friendly URLs.
Mechanism Appends jsessionid to URLs. Uses a framework's routing or a filter to map a public URL to an internal resource.
Technology JSP encodeURL(), c:url tag. Spring Boot, JAX-RS, or a Filter like Tuckey's.
Modern Usage Legacy. Rarely needed today. Standard Practice. Essential for any modern web application.

Recommendation:

  • If you are starting a new project, use a modern framework like Spring Boot or Jakarta EE (formerly Java EE) with JAX-RS. The annotation-based routing is clean, powerful, and the industry standard.
  • If you are maintaining a legacy Servlet/JSP application without a framework, the Tuckey URLRewriteFilter is an excellent choice to add URL rewriting capabilities without a massive rewrite.
分享:
扫描分享到社交APP
上一篇
下一篇