我可以在 Java Servlet 过滤器中拦截和更改 HTTPServletRequest 的请求 url 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1351228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:13:15  来源:igfitidea点击:

Can I intercept and change the request url of a HTTPServletRequest within a Java Servlet filter?

javaservlets

提问by duffymo

I have a Java web application which manages data for many clubs. I would like the application to show club information depending on the URL that is typed in.

我有一个 Java Web 应用程序,用于管理许多俱乐部的数据。我希望应用程序根据输入的 URL 显示俱乐部信息。

Eg. If you enter "localhost:8080/MyApp/Club1" ...then the app should strip out the end of the requst url (Club1), do a lookup in the database for the club, and add this to the session. Then all database requests can look up data depending on which club is in the session.

例如。如果您输入“localhost:8080/MyApp/Club1”……那么应用程序应该去掉请求 url (Club1) 的末尾,在数据库中查找俱乐部,并将其添加到会话中。然后所有数据库请求都可以根据会话中的哪个俱乐部来查找数据。

If you enter "localhost:8080/MyApp/Club2", you get club to registered in the session, and all database requests are for club 2.

如果您输入“localhost:8080/MyApp/Club2”,您会在会话中注册俱乐部,并且所有数据库请求都是针对俱乐部 2 的。

The way I thought I may do this is to use a servlet filter that calls HTTPServletRequest().getRequestURL(), and strips out the club name from the request url, to lookup the club from the database.

我认为我可以这样做的方法是使用调用 HTTPServletRequest().getRequestURL() 的 servlet 过滤器,并从请求 url 中去除俱乐部名称,以从数据库中查找俱乐部。

But then I wan't to change the request URL to be http://localhost:8080/MyAppso that the application works as normal. However, I don't think I am able to do this?

但是我不想将请求 URL 更改为http://localhost:8080/MyApp以便应用程序正常工作。但是,我不认为我能够做到这一点?

Anyone any ideas of how to do this, or if there is a better approach?

任何人都知道如何做到这一点,或者是否有更好的方法?

回答by duffymo

I don't think a filter is the proper way to do it. What you're describing about changing behavior based on club membership is logic that belongs inside your service layer, where it can be reused.

我不认为过滤器是正确的方法。您所描述的关于基于俱乐部会员资格改变行为的逻辑属于您的服务层,可以在其中重用。

A better way to do it would be to forget about filters and just program your servlet. Pass the club name as a parameter, use it to do a lookup in a map of the URL for that club, and have your servlet use the RequestDispatcher to redirect to the URL for that club. I don't see any advantage to intercepting it a heartbeat earlier with a Filter.

更好的方法是忘记过滤器,只编写 servlet。将俱乐部名称作为参数传递,使用它在该俱乐部的 URL 映射中进行查找,并让您的 servlet 使用 RequestDispatcher 重定向到该俱乐部的 URL。我认为使用过滤器提前拦截它没有任何优势。

If you were using Spring, I'd recommend putting this into your service and let the web MVC tier handle mapping and routing of requests.

如果您使用的是 Spring,我建议将其放入您的服务中,并让 Web MVC 层处理请求的映射和路由。

This is one of those cases where if it's too difficult and convoluted to do what you want, you're probably trying the wrong thing. There are easier ways to do this, and filters aren't even close.

这是其中一种情况,如果做你想做的事情太困难和复杂,你可能会尝试错误的事情。有更简单的方法可以做到这一点,过滤器甚至不接近。

回答by Adrian Pronk

Take a look at urlrewritefilter. It's a servlet filter that can modify the request URL before your servlet sees it. It is often used to transform query parameters to or from path parameters.

看看urlrewritefilter。它是一个 servlet 过滤器,可以在您的 servlet 看到它之前修改请求 URL。它通常用于将查询参数转换为路径参数或从路径参数转换。

If you google for it, you'll see it come up in the stack-traces of some pretty high-profile java applications :)

如果你用谷歌搜索它,你会看到它出现在一些非常引人注目的 Java 应用程序的堆栈跟踪中:)

回答by adatapost

Core J2EE Patterns - Intercepting Filter

核心 J2EE 模式 - 拦截过滤器

SUMMARY:Create pluggable filters to process common services in a standard manner without requiring changes to core request processing code. The filters intercept incoming requests and outgoing responses, allowing preprocessing and post-processing. We are able to add and remove these filters unobtrusively, without requiring changes to our existing code.

总结:创建可插拔过滤器,以标准方式处理公共服务,无需更改核心请求处理代码。过滤器拦截传入的请求和传出的响应,允许预处理和后处理。我们能够不引人注目地添加和删除这些过滤器,而无需更改我们现有的代码。

回答by Vinay Sajip

In your servlet's do_GET/do_POST, you can interpret the first part of the URI as a club, add it to the session (using application scope) if it's not already there, then delegate to other code which only looks at the rest of the URI and uses the in-session club where appropriate.

在您的 servlet 的do_GET/ 中do_POST,您可以将 URI 的第一部分解释为俱乐部,如果它不存在,则将其添加到会话(使用应用程序范围),然后委托给其他代码,该代码仅查看 URI 的其余部分并使用会议期间的俱乐部(如适用)。