J'ai besoin de gérer les demandes comme suit:
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)
Il doit accepter toute sorte de caractère de la valeur située entre www.example.com/show/
et ?
. Veuillez noter que la valeur qui serait localisée serait une valeur unique et non le nom d'une action.
Par exemple: /show/abcd/efg
et /show/lkikf?name=Jack
dans lequel la première demande doit rediriger l'utilisateur vers la page abcd/efg
(car c'est un nom) et le second devrait rediriger l'utilisateur vers la page lkikf
avec la valeur du nom du paramètre.
J'ai le contrôleur suivant pour le gérer, mais le problème est lorsque j'ai/dans l'adresse, le contrôleur est incapable de le gérer.
@RequestMapping(value = "/{mystring:.*}", method = RequestMethod.GET)
public String handleReqShow(
@PathVariable String mystring,
@RequestParam(required = false) String name,
@RequestParam(required = false) String family, Model model) {
J'ai utilisé l'expression régulière qui ne fonctionnait pas.
/^[ A-Za-z0-9_@./#&+-]*$/
Vous devez créer deux méthodes, puis une ayant l'annotation @RequestMapping(value = { "/{string:.+}" })
et l'autre ayant @RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" })
, puis agir en conséquence dans chacune, car vous ne pouvez pas avoir de variables de chemin optionnelles).
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";
}
}
Une autre façon de faire est:
@RequestMapping(value = "test_handler/**", method = RequestMethod.GET)
... et votre gestionnaire de test peut être "/ test_hanlder/a/b/c" et vous obtiendrez la valeur entière en utilisant le mécanisme suivant.
requestedUri = (String)
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
Le premier ne fonctionne pas car vous essayez de gérer une URL entièrement nouvelle qui n'est pas réellement mappée sur votre contrôleur.
www.example.com/show/abcd/efg?name=alex&family=moore (does not work)
Le mappage correct pour l'URL ci-dessus pourrait être comme le code ci-dessous.
@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) {
J'ai essayé le concept similaire lorsque mon seul contrôleur est utilisé pour gérer plusieurs types de demandes.
Vous pouvez encoder des barres obliques sur l'interface utilisateur avec% 2f: http://www.example.com/show/abcd%2fefg?name=alex&family=moore
. Vous devez maintenant configurer Spring pour gérer les barres obliques. Exemple de configuration simple:
@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);
}
}
}
Vous pouvez définir des règles pour éviter cela
<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 ajoutez ceci à votre WEB-INF
<urlrewrite>
<rule>
<from>^/(10\..*)$</from> <!-- Tweak this rule to meet your needs -->
<to>/Show?temp=$1</to>
</rule>
</urlrewrite>
Le mappeur de chemins par défaut Spring MVC utilise le /
comme délimiteur pour les variables de chemin, quoi qu'il arrive.
La bonne façon de gérer cette demande serait d'écrire un mappeur de chemin personnalisé, qui changerait cette logique pour la méthode de gestionnaire particulière et déléguerait par défaut pour les autres méthodes de gestionnaire.
Cependant, si vous connaissez le nombre maximal possible de barres obliques dans votre valeur, vous pouvez en fait écrire un gestionnaire qui accepte les variables de chemin facultatives, et que dans la méthode elle-même, assembler la valeur à partir des parties de variable de chemin, voici un exemple qui fonctionnerait pour max une barre oblique, vous pouvez facilement l'étendre à trois ou quatre
@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
}
Vous pouvez attraper toutes les variables de chemin à l'intérieur de la carte, la carte @PathVariable Map<String, String> pathVariables
, mais l'inconvénient est que la partie statique du mappage doit énumérer toutes les variations possibles
Essayez d'échapper à la barre oblique. Regex: /^[ A-Za-z0-9_@.\/#&+-]*$/