Spring MVC(3.0)は、末尾のスラッシュがある場合とない場合のURLを同じURLと見なします。
例えば:
http://www.example.org/data/something = http://www.example.org/data/something/
末尾のスラッシュを使用してURLをリダイレクトする必要があります
それなしでURLに:
私は内部的にこれをアプリケーションで行う必要があります(だからApacheなどでルールを書き換えないでください)。
その方法は次のとおりです。
@ResponseStatus(value=HttpStatus.MOVED_PERMANENTLY)
@RequestMapping(value = "/data/something/")
public String dataSomethingRedirect(...) {
return "redirect:/data/something";
}
しかし、これには通常2つの問題があります。
- 多すぎるコントローラ
- パラメータの問題:間違ったエンコーディングのようなもの
質問
すべてのURLを傍受する方法はありますか。それらに末尾のスラッシュがある場合は、スラッシュなしでそれらを相対URLにリダイレクトしますか?
回答:
回答№1の13Web設定に必要なすべての書き換え規則をリストできます。
これらの多くがない場合は、このようにリダイレクトビューを設定できます。
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/my/path/", "/my/path")
.setKeepQueryParams(true)
.setStatusCode(HttpStatus.PERMANENT_REDIRECT);
}
またはあなたはカスタムを作成することができます HandlerInterceptor
しかし、インターセプターはリクエストが特定のものにマッピングされる前に発生します。 Controller.action
そして、あなたは「そのコンテキストでコントローラとアクションを知る方法がありませんでした。
あなたが手に入れたのは、HTTPServlet APIとリクエスト+レスポンスだけです。
response.sendRedirect("http://example.org/whitout-trailing-slash");
読みたくない答え
HTTPを考えるとき、この振る舞い(末尾のスラッシュ付きのURL =それなしのURL)は完全に "有効"です。少なくともこれはSpringのデフォルトの振る舞いです。 useTrailingSlashMatch
(Javadocを参照)。
そのため、フロントエンドサーバーで書き換え/リダイレクトの規則を使用すると解決策が得られます。しかし、繰り返しますが、私はあなたの制約を知りません(多分あなたはこれについて詳しく述べることができ、私たちは他の解決策を見つけ出すことができますか?)
回答№2の11
Spring WebのサーブレットにUrlRewriteFilterを使用して入力する前にこれを実行するのが最善の選択肢だと思います。これにより、リダイレクト規則がコントローラーに影響を与えないようになります。
mod_rewriteを使ったApacheではなく、.warプロジェクトでルールを書くことに注意してください。
ここに行く googlecodeに関する図書館のプロジェクトのために。
urlrewrite.xmlに次のように書きます。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.1//EN" "http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd">
<urlrewrite>
<rule match-type="regex">
<note>Remove trailing slash</note>
<from>^(.*)/$</from>
<to type="redirect">$1</to>
</rule>
</urlrewrite>
アプリケーションのweb.xmlに、以下を追加します。
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/urlrewrite.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
注意してください、web.xmlのフィルタの宣言順は重要です、それで、何よりも春の前にこれを宣言しようとしてください。
もちろん、これはUrlRewriteFilterが実行できることのほんの一部にすぎません。
よろしく。
回答№3の場合は3
これは通常、SpringのURLRewriteFilterで私のために働きます。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://www.tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite>
<rule>
<note>Remove trailing slash for SEO purposes</note>
<from>/**/</from>
<to type="permanent-redirect">%{context-path}/$1</to>
</rule>
</urlrewrite>
答え№4の3
春3.0にこれがあったかどうかわからないが、春3.1 RequestMappingHandlerMapping 「useTrailingSlashMatch」プロパティを設定できます。デフォルトではtrueです。
それをfalseに切り替えることであなたの問題は解決すると思いますただし、RequestMappingHandlerMappingによってアプリケーション全体で処理されるすべてのマッピングに影響を与える可能性があります。
回答№5の場合は0
私は@Brian Clozelに同意します:あなたが望むことをするのは良い考えではないと思います。それで、なぜあなたはそれを必要としますか?
とにかく、私は最も簡単な解決策はカスタムを書くことだと思います javax.servlet.Filter
。だから、春の依存関係はありません。リクエストURLがスラッシュで終わっているなら、あなたはそれなしで同じURLにリダイレクトする必要があります。しかし注意:
すべてのパラメータ(GETおよびPOST)をGETパラメータとして追加する必要があります。あなたのアプリケーションは メソッドにとらわれない?
エンコーディングに関していくつか問題があるかもしれません。 フィルタでは、POSTパラメータを必要なエンコーディングにエンコードできます。しかし、GETパラメータのデフォルトのエンコーディングはアプリケーションでは設定されていません。 (Tomcatの場合)server.xmlで設定され、デフォルト値はISO-8859-1です。
がんばろう!
答え№6の場合は0
SEOに基づいて、私は区別することが重要だと思います。
末尾のスラッシュで終わっているURLの場合Uddhav Kambliが言うように、存在し、検索エンジンで索引付けされており、インターネット上にリンクがある場合は、恒久的なリダイレクト(301)が必要です。標準のリダイレクト(302)は、URLが重複しているよりも優れていますが、十分ではありません。
ただし、URLが存在しなかった場合、インターネット上でインデックス化されず、外部リンクがないため、URLは存在しません。したがって、404というページが見つからない方が適しています。
WEB-INF / urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.1//EN" "http://www.tuckey.org/res/dtds/urlrewrite3.1.dtd">
<urlrewrite>
<rule match-type="regex">
<note>Remove trailing slash</note>
<from>^(.+)/$</from>
<set type="status">404</set>
<to>null</to>
</rule>
</urlrewrite>
そして設定を完了するために…
WEB-INF / web.xmlに追加
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confPath</param-name>
<param-value>/WEB-INF/urlrewrite.xml</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
Maven
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.3</version>
</dependency>
回答№7は0
@ConfigurationのどこかにErrorViewResolver Beanを使用することで、これをはるかに簡単に処理できることもわかりました。
@Autowired
private DefaultErrorViewResolver defaultErrorViewResolver;
@Bean
ErrorViewResolver errorViewResolver() {
return new ErrorViewResolver() {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
if(model.containsKey("path") && !model.get("path").toString().endsWith("/")) {
return new ModelAndView("redirect:"+model.get("path") + "/");
}
return defaultErrorViewResolver.resolveErrorView(request, status, model);
}
};
}
これが良いやり方なのか悪いやり方なのかわかりませんが、それは私の状況では効果的であり、任意のパス "foo"に対して私がする必要があることと全く同じです。