Probabilmente, è un brutto scherzo, volevo solo esplorare l'estensibilità di Spring @MVC. Ecco un numero personalizzato PathMatcher
. Utilizza lo $
nel modello come indicatore finale - se il modello termina con esso, il marcatore viene rimosso e il modello corrisponde al corrispondente predefinito, ma se il modello ha $
nel mezzo (ad esempio ...$.*
), tale modello non corrisponde.
public class CustomPathMatcher implements PathMatcher {
private PathMatcher target;
public CustomPathMatcher() {
target = new AntPathMatcher();
}
public String combine(String pattern1, String pattern2) {
return target.combine(pattern1, pattern2);
}
public String extractPathWithinPattern(String pattern, String path) {
if (isEncoded(pattern)) {
pattern = resolvePattern(pattern);
if (pattern == null) return "";
}
return target.extractPathWithinPattern(pattern, path);
}
public Map<String, String> extractUriTemplateVariables(String pattern,
String path) {
if (isEncoded(pattern)) {
pattern = resolvePattern(pattern);
if (pattern == null) return Collections.emptyMap();
}
return target.extractUriTemplateVariables(pattern, path);
}
public Comparator<String> getPatternComparator(String pattern) {
final Comparator<String> targetComparator = target.getPatternComparator(pattern);
return new Comparator<String>() {
public int compare(String o1, String o2) {
if (isEncoded(o1)) {
if (isEncoded(o2)) {
return 0;
} else {
return -1;
}
} else if (isEncoded(o2)) {
return 1;
}
return targetComparator.compare(o1, o2);
}
};
}
public boolean isPattern(String pattern) {
if (isEncoded(pattern)) {
pattern = resolvePattern(pattern);
if (pattern == null) return true;
}
return target.isPattern(pattern);
}
public boolean match(String pattern, String path) {
if (isEncoded(pattern)) {
pattern = resolvePattern(pattern);
if (pattern == null) return false;
}
return target.match(pattern, path);
}
public boolean matchStart(String pattern, String path) {
if (isEncoded(pattern)) {
pattern = resolvePattern(pattern);
if (pattern == null) return false;
}
return target.match(pattern, path);
}
private boolean isEncoded(String pattern) {
return pattern != null && pattern.contains("$");
}
private String resolvePattern(String pattern) {
int i = pattern.indexOf('$');
if (i < 0) return pattern;
else if (i == pattern.length() - 1) {
return pattern.substring(0, i);
} else {
String tail = pattern.substring(i + 1);
if (tail.startsWith(".")) return null;
else return pattern.substring(0, i) + tail;
}
}
}
Config:
<bean id = "pathMatcher" class = "sample.CustomPathMatcher" />
<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name = "pathMatcher" ref="pathMatcher" />
</bean>
<bean class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name = "pathMatcher" ref="pathMatcher" />
</bean>
e l'uso (dato "/hello/1.2.3", value
è "1.2.3"):
@RequestMapping(value = "/hello/{value}$", method = RequestMethod.GET)
public String hello(@PathVariable("value") String value, ModelMap model)
EDIT:: Ora non si rompe la "barra finale non importa" regola
Questo ha fatto il trucco, grazie Skaffman. Ma ha rotto un'altra parte dell'app ... il contentNegotiatingViewResolver che mappa un'estensione ".json" su Jackson non funziona più. Qualche idea su come risolvere questo problema? – nickdos
Ordinato il problema con contentNegotiatingViewResolver associando esplicitamente il mio metodo controller all'URL incluso ".json". Per esempio. usando l'annotazione: @RequestMapping (value = "/search.json", method = RequestMethod.GET). C'è una soluzione migliore per questo? – nickdos
Hai provato '@RequestMapping (value ="/search * ")'? – skaffman