Подтвердить что ты не робот

Как обрабатывать запросы, которые включают в себя косые черты (/)?

Мне нужно обрабатывать запросы следующим образом:

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 (потому что это имя), а второй должен перенаправить пользователя на страницу 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)     {

Я использовал следующее регулярное выражение, которое не сработало.

 /^[ [email protected]/#&+-]*$/
4b9b3361

Ответ 1

Вам нужно создать два метода, а затем иметь @RequestMapping(value = { "/{string:.+}" }) аннотацию, а другую - @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";
    }
}

Ответ 2

Другой способ:

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

... и ваш тестовый обработчик может быть "/test_hanlder/a/b/c", и вы получите всю ценность, используя следующий механизм.

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

Ответ 3

Первый не работает, потому что вы пытаетесь обработать совершенно новый 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)     {

Я пробовал аналогичную концепцию, когда мой один контроллер используется для обработки нескольких типов запросов.

Ответ 4

Вы можете определить правила, чтобы избежать этого.

<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>

Ответ 5

Попробуйте избежать косой черты. Regex: /^[ A-Za-z0[email protected]\/#&+-]*$/

Ответ 6

По умолчанию Spring MVC pathperper использует / как разделитель для переменных пути, независимо от того, что.

Правильный способ обработки этого запроса состоял бы в том, чтобы написать собственный сопоставитель маршрутов, который изменил бы эту логику для конкретного метода обработчика и делегировал значение по умолчанию для других методов обработчика.

Однако, если вы знаете максимально возможное количество косых черт в своем значении, вы можете написать обработчик, который принимает необязательные переменные пути, а не в самом методе, собрать значение из частей переменной пути, вот пример который будет работать для максимальной косой черты, вы можете легко расширить его до трех или четырех

@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, но недостатком является то, что статическая часть отображения должна перечислить все возможные варианты

Ответ 7

Вы можете кодировать косые черты в пользовательском интерфейсе с помощью% 2f: 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);
        }
    }

}