web-dev-qa-db-ja.com

スラッシュ(/)を含むリクエストを処理する方法は?

次のようにリクエストを処理する必要があります。

www.example.com/show/abcd/efg?name=alex&family=moore   (does not work)
www.example.com/show/abcdefg?name=alex&family=moore   (works)
www.example.com/show/abcd-efg?name=alex&family=moore   (works)

www.example.com/show/?の間にある値から任意の種類の文字を受け入れる必要があります。そこに配置される値は、アクションの名前ではなく単一の値になることに注意してください。

例:/show/abcd/efgおよび/show/lkikf?name=Jackでは、最初の要求はユーザーをページabcd/efg(名前のため)にリダイレクトし、2番目の要求はユーザーを値とともにlkikfページにリダイレクトしますパラメータ名の。

私はそれを処理するために次のコントローラを持っていますが、問題はコントローラがそれを処理できないアドレスに/がある場合です。

@RequestMapping(value = "/{mystring:.*}", method = RequestMethod.GET)
public String handleReqShow(
            @PathVariable String mystring,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String family, Model model)     {

動作しない次の正規表現を使用しました。

 /^[ A-Za-z0-9_@./#&+-]*$/
34
Jack

オプションの パス変数を使用できないため、2つのメソッドを作成し、1つは@RequestMapping(value = { "/{string:.+}" })アノテーションを使用し、もう1つは@RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" })を使用して、それぞれに応じて動作する必要があります。

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/show")
public class HelloController {

    @RequestMapping(value = { "/{string:.+}" })
    public String handleReqShow(@PathVariable String string,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String family, Model model) {
        System.out.println(string);
        model.addAttribute("message", "I am called!");
        return "hello";
    }

    @RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" })
    public String whatever(@PathVariable String string,
            @PathVariable String mystring,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String family, Model model) {
        System.out.println(string);
        System.out.println(mystring);
        model.addAttribute("message", "I am called!");
        return "hello";
    }
}
18
Arpit

別の方法は次のとおりです。

@RequestMapping(value = "test_handler/**", method = RequestMethod.GET)

...また、テストハンドラーを「/ test_hanlder/a/b/c」にすることができ、次のメカニズムを使用して値全体を取得します。

requestedUri = (String) 
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
21

実際にコントローラーにマップされていない完全に新しいURLを処理しようとしているため、最初のURLは機能していません。

www.example.com/show/abcd/efg?name=alex&family=moore   (does not work)

上記のURLの正しいマッピングは、次のコードのようになります。

@RequestMapping(value = {"/{mystring:.*}" , "/{mystring:.*}/{mystring2:.*}"}, method = RequestMethod.GET)
public String handleReqShow(
        @PathVariable String mystring,
        @PathVariable String mystring2,
        @RequestParam(required = false) String name,
        @RequestParam(required = false) String family, Model model)     {

1つのコントローラーを使用して複数のタイプの要求を処理する場合、同様の概念を試しました。

4
Ankur Jain

%2fを使用してUIにスラッシュをエンコードできました:http://www.example.com/show/abcd%2fefg?name=alex&family=moore。ここで、スラッシュを処理するようにSpringを構成する必要があります。簡単な設定例:

@RestController
public class TestController {

    @GetMapping("{testId:.+}")
    public String test(@PathVariable String testId) {
        return testId;
    }


    @GetMapping("{testId:.+}/test/{messageId}")
    public String test2(@PathVariable String testId, @PathVariable String messageId) {
        return testId + " " + messageId;
    }

    //Only if using Spring Security
    @Configuration
    public static class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
        @Bean
        public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
            DefaultHttpFirewall firewall = new DefaultHttpFirewall();
            firewall.setAllowUrlEncodedSlash(true);
            return firewall;
        }
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
        }
    }


    @Configuration
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public static class SpringMvcConfig extends WebMvcConfigurerAdapter {
        @Override
        public void configurePathMatch(PathMatchConfigurer configurer) {
            UrlPathHelper urlPathHelper = new UrlPathHelper();
            urlPathHelper.setUrlDecode(false);
            configurer.setUrlPathHelper(urlPathHelper);
        }
    }

}
3

あなたはそれを避けるためにルールを定義することができます

<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>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

rules.xmlはこれをWEB-INFに追加します

<urlrewrite>
    <rule>
       <from>^/(10\..*)$</from> <!-- Tweak this rule to meet your needs -->
       <to>/Show?temp=$1</to>
    </rule>
</urlrewrite>
3
Daniel Newtown

デフォルトのSpring MVCパスマッパーは、/をパス変数の区切り文字として使用します。

この要求を処理する適切な方法は、特定のハンドラーメソッドのこのロジックを変更し、他のハンドラーメソッドのデフォルトに委任するカスタムパスマッパーを作成することです。

ただし、値のスラッシュの最大可能カウントがわかっている場合は、実際にはオプションのパス変数を受け入れるハンドラーを記述し、メソッド自体ではなく、パス変数部分から値を組み立てることができます。これは動作する例です最大1つのスラッシュの場合、簡単に3つまたは4つに拡張できます

@RequestMapping(value = {"/{part1}", "/{part1}/{part2}"}, method = RequestMethod.GET)
public String handleReqShow(
        @PathVariable Map<String, String> pathVariables,
        @RequestParam(required = false) String name,
        @RequestParam(required = false) String family, Model model) {
    String yourValue = "";
    if (pathVariables.containsKey("part1")) {
        String part = pathVariables.get("part1");
        yourValue += " " + part;
    }
    if (pathVariables.containsKey("part2")) {
        String part = pathVariables.get("part2");
        yourValue += " /" + part;
    }
    // do your stuff

}

マップ内のすべてのパス変数、マップ@PathVariable Map<String, String> pathVariablesをキャッチできますが、欠点は、マッピングの静的な部分がすべての可能なバリエーションを列挙する必要があることです

2
Master Slave

スラッシュをエスケープしてみてください。正規表現:/^[ A-Za-z0-9_@.\/#&+-]*$/

2
SKalariya