【问题标题】:How to implement URL shortners like takemeto/google如何实现 URL 缩短器,例如带我到/google
【发布时间】:2022-10-13 06:26:46
【问题描述】:
我知道如何设计和实现 URL 缩短服务,但我想知道如何在下面设计
- 当我写 go/google 时;它带我去 google.com
- 当我编写 go/acc 时,它会将我带到 Accenture.com
/ 的右侧将在 URL 更短服务中配置,但是我如何设计左侧部分,以便当我在地址栏中编写 go/ 时,它会被服务点击以选择与 google 或 acc 映射的实际 URL 并重定向
【问题讨论】:
-
我会投票结束这个问题,因为可能有数百种方法可以实现这一点;太多了,这里就不一一列举了。此外,对其中任何一个的完整答案可能需要很多页甚至一整本书。 edit 您的问题不是要求一种方法,而是要关注您在选择一种方法并尝试实施它后遇到的更具体的问题。
标签:
java
url
redirect
url-rewriting
url-shortener
【解决方案1】:
正如@StephenOstermiller 在他的评论中指出的那样,可能有数百种方法可以实现所需的行为。
无论如何,假设一个简单的方法,使用标准Java Servlet API,您可以尝试以下类似的方法。
- 首先,实现和register, either programmatically or using a
web.xml file,HttpServlet 用于处理 URL 缩短请求。您可以将您的 servlet 映射到 '/go' servlet 路径。
- 使用
HttpServletRequest 提供的不同方法分析您收到的URI,例如使用getPathInfo 和getRequestURI。这个想法是能够提取标识您的请求应重定向到的实际服务的 URI 片段。 String 类提供的方法可以在这一步中提供帮助。
- 获取作为上一步结果获得的 URI 片段与实际服务之间的映射,可能是查询数据库或任何其他方式。在一个简单的用例中,内存中的
Map 可以解决问题。
- 一旦确定,发出
302 HTTP 重定向响应,并带有与实际服务对应的Location 标头。如有必要,请使用在步骤 2 中获得的信息来附加查询参数或您认为适合构建实际服务 URI 的任何其他信息。 HttpServletResponse 提供了直接的 sendRedirect 方法来执行此临时重定向。如果您更喜欢使用永久重定向,即使用301 HTTP 状态码,则需要显式提供此状态码和相应的Location 标头;请看这个related SO question。
例如:
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GoServlet extends HttpServlet {
private static final Map<String, String> redirectionMap = new HashMap<>();
static {
redirectionMap.put("google", "https://www.google.com");
redirectionMap.put("acc", "https://www.accenture.com");
}
@Override
public void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
String redirectionKey = request.getPathInfo();
if (redirectionKey != null && redirectionKey.startsWith("/")) {
redirectionKey = redirectionKey.substring(1);
}
if (!redirectionMap.containsKey(redirectionKey)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String redirectionUrl = redirectionMap.get(redirectionKey);
response.sendRedirect(redirectionUrl);
}
}
如果就像您之前的问题一样,您正在使用其他库,例如 Spring 和 Spring MVC,您可以为相同的目的定义一个简单的控制器。可以这样定义:
@RequestMapping(path = "/go/{redirectKey}", method = RequestMethod.GET)
public void expandUrl(@PathVariable("redirectKey") final String redirectKey, HttpServletResponse response) throws IOException {
// where redirectionMap has been defined as above
if (!redirectionMap.containsKey(redirectionKey)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String redirectionUrl = redirectionMap.get(redirectionKey);
response.sendRedirect(redirectionUrl);
}
请原谅我的简单代码,它们只是简单重定向的基本示例,但它们举例说明了为实现所需功能而需要执行的任务。
我认为这种重定向机制不会以这种方式实现,使用 ad hoc 应用程序,但可能是某种 L7 网络设备或类似的东西。