Spring 3 요청 맵핑:경로 값 가져오기
path 값을 취득할 수 있는 방법이 있습니까?requestMapping
@PathVariable
값이 해석되었습니까?
즉, 다음과 같습니다./{id}/{restOfTheUrl}
해석할 수 있어야 합니다./1/dir1/dir2/file.html
안으로id=1
그리고.restOfTheUrl=/dir1/dir2/file.html
어떤 아이디어라도 주시면 감사하겠습니다.
URL의 일치하지 않는 부분은 다음과 같은 이름의 요청 속성으로 표시됩니다.HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
:
@RequestMapping("/{id}/**")
public void foo(@PathVariable("id") int id, HttpServletRequest request) {
String restOfTheUrl = new AntPathMatcher().extractPathWithinPattern(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),request.getRequestURI());
...
}
방금 내 문제와 일치하는 문제를 발견했어.Handler Mapping 상수를 사용하여 작은 유틸리티를 작성할 수 있었습니다.
/**
* Extract path from a controller mapping. /controllerUrl/** => return matched **
* @param request incoming request.
* @return extracted path
*/
public static String extractPathFromPattern(final HttpServletRequest request){
String path = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String ) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
AntPathMatcher apm = new AntPathMatcher();
String finalPath = apm.extractPathWithinPattern(bestMatchPattern, path);
return finalPath;
}
여기 오래 있었는데 이걸 올리네요.누군가에게 유용할 수도 있어요.
@RequestMapping( "/{id}/**" )
public void foo( @PathVariable String id, HttpServletRequest request ) {
String urlTail = new AntPathMatcher()
.extractPathWithinPattern( "/{id}/**", request.getRequestURI() );
}
Fabien Kruba의 이미 훌륭한 답변을 바탕으로, 나는 그 대답에 대해 생각해 보았다.**
URL의 일부는 주석을 통해 컨트롤러 메서드에 파라미터로 주어질 수 있습니다.이는 다음과 같습니다.@RequestParam
그리고.@PathVariable
항상 명시적으로 필요한 유틸리티 방식을 사용하는 것이 아니라HttpServletRequest
다음은 구현 방법의 예입니다.누군가 유용하게 썼으면 좋겠네요.
주석과 인수 리졸버를 만듭니다.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WildcardParam {
class Resolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterAnnotation(WildcardParam.class) != null;
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
return request == null ? null : new AntPathMatcher().extractPathWithinPattern(
(String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE),
(String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE));
}
}
}
method 인수 리졸버를 등록합니다.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new WildcardParam.Resolver());
}
}
컨트롤러 핸들러 메서드의 주석을 사용하여**
URL의 일부:
@RestController
public class SomeController {
@GetMapping("/**")
public void someHandlerMethod(@WildcardParam String wildcardParam) {
// use wildcardParam here...
}
}
빌트인을 사용해야 합니다.pathMatcher
:
@RequestMapping("/{id}/**")
public void test(HttpServletRequest request, @PathVariable long id) throws Exception {
ResourceUrlProvider urlProvider = (ResourceUrlProvider) request
.getAttribute(ResourceUrlProvider.class.getCanonicalName());
String restOfUrl = urlProvider.getPathMatcher().extractPathWithinPattern(
String.valueOf(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)),
String.valueOf(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)));
Spring 3 MVC에서는 아직 지원하지 않는 것 같아서 Tuckey URLRewriteFilter를 사용하여 '/' 문자가 포함된 경로 요소를 처리했습니다.
이 필터를 앱에 넣고 XML 구성 파일을 제공합니다.이 파일에서는 리라이트 규칙을 제공합니다.이 규칙을 사용하여 Spring MVC가 @RequestParam을 사용하여 적절하게 처리할 수 있는 요청 매개 변수로 변환합니다.
WEB-INF/web.xml:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<!-- map to /* -->
WEB-INF/urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
"http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
<urlrewrite>
<rule>
<from>^/(.*)/(.*)$</from>
<to last="true">/$1?restOfTheUrl=$2</to>
</urlrewrite>
컨트롤러 방식:
@RequestMapping("/{id}")
public void handler(@PathVariable("id") int id, @RequestParam("restOfTheUrl") String pathToFile) {
...
}
네, 더restOfTheUrl
필요한 값만 반환하는 것은 아니지만 다음 방법으로 값을 얻을 수 있습니다.UriTemplate
매칭
이 문제를 해결했습니다.이 문제에 대한 유효한 해결책은 다음과 같습니다.
@RequestMapping("/{id}/**")
public void foo(@PathVariable("id") int id, HttpServletRequest request) {
String restOfTheUrl = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
/*We can use UriTemplate to map the restOfTheUrl*/
UriTemplate template = new UriTemplate("/{id}/{value}");
boolean isTemplateMatched = template.matches(restOfTheUrl);
if(isTemplateMatched) {
Map<String, String> matchTemplate = new HashMap<String, String>();
matchTemplate = template.match(restOfTheUrl);
String value = matchTemplate.get("value");
/*variable `value` will contain the required detail.*/
}
}
내가 한 방법은 이렇다.요청한 내용을 변환하는 방법을 볼 수 있습니다.파일 시스템 경로에 대한 URI(이 SO 질문의 내용).보너스: 파일로 응답하는 방법도 있습니다.
@RequestMapping(value = "/file/{userId}/**", method = RequestMethod.GET)
public void serveFile(@PathVariable("userId") long userId, HttpServletRequest request, HttpServletResponse response) {
assert request != null;
assert response != null;
// requestURL: http://192.168.1.3:8080/file/54/documents/tutorial.pdf
// requestURI: /file/54/documents/tutorial.pdf
// servletPath: /file/54/documents/tutorial.pdf
// logger.debug("requestURL: " + request.getRequestURL());
// logger.debug("requestURI: " + request.getRequestURI());
// logger.debug("servletPath: " + request.getServletPath());
String requestURI = request.getRequestURI();
String relativePath = requestURI.replaceFirst("^/file/", "");
Path path = Paths.get("/user_files").resolve(relativePath);
try {
InputStream is = new FileInputStream(path.toFile());
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (IOException ex) {
logger.error("Error writing file to output stream. Path: '" + path + "', requestURI: '" + requestURI + "'");
throw new RuntimeException("IOError writing file to output stream");
}
}
private final static String MAPPING = "/foo/*";
@RequestMapping(value = MAPPING, method = RequestMethod.GET)
public @ResponseBody void foo(HttpServletRequest request, HttpServletResponse response) {
final String mapping = getMapping("foo").replace("*", "");
final String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
final String restOfPath = url.replace(mapping, "");
System.out.println(restOfPath);
}
private String getMapping(String methodName) {
Method methods[] = this.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName() == methodName) {
String mapping[] = methods[i].getAnnotation(RequestMapping.class).value();
if (mapping.length > 0) {
return mapping[mapping.length - 1];
}
}
}
return null;
}
@Daniel Jay Marcaida 답변 개선
@RequestMapping( "/{id}/**" )
public void foo( @PathVariable String id, HttpServletRequest request ) {
String restOfUrl = new AntPathMatcher()
.extractPathWithinPattern(
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString());
}
또는
@RequestMapping( "/{id}/**" )
public void foo( @PathVariable String id, HttpServletRequest request ) {
String restOfUrl = new AntPathMatcher()
.extractPathWithinPattern(
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),
request.getServletPath());
}
비슷한 문제가 있어 다음과 같이 해결했습니다.
@RequestMapping(value = "{siteCode}/**/{fileName}.{fileExtension}")
public HttpEntity<byte[]> getResource(@PathVariable String siteCode,
@PathVariable String fileName, @PathVariable String fileExtension,
HttpServletRequest req, HttpServletResponse response ) throws IOException {
String fullPath = req.getPathInfo();
// Calling http://localhost:8080/SiteXX/images/argentine/flag.jpg
// fullPath conentent: /SiteXX/images/argentine/flag.jpg
}
주의:req.getPathInfo()
합니다(경로에는 「경로」가 포함됩니다).{siteCode}
★★★★★★★★★★★★★★★★★」{fileName}.{fileExtension}
)이 때문에, 간단하게 처리할 필요가 있습니다.
언급URL : https://stackoverflow.com/questions/3686808/spring-3-requestmapping-get-path-value
'IT' 카테고리의 다른 글
쇼트 코드를 사용하여 워드프레스 투고의 페이지 제목을 콘텐츠에 포함시키는 방법 (0) | 2023.03.04 |
---|---|
Spring Boot: Apache Commons File Upload를 사용한 대용량 스트리밍 파일 업로드 (0) | 2023.03.04 |
JSON 개체 스트림을 jq를 사용하여 배열로 변환하는 방법 (0) | 2023.03.04 |
TypeScript 컴파일의 실험용 장식자 경고 (0) | 2023.03.04 |
재스트 반응 테스트:지연 후 상태 확인 (0) | 2023.03.04 |