我有Spring rest控制器,它在Project
实体上提供操作。所有方法使用相同的实体访问代码。我不想在所有方法中复制和粘贴@PathVariable
参数,所以我做了类似的事情。
@RestController
@RequestMapping("/projects/{userName}/{projectName}")
public class ProjectController {
@Autowired
ProjectService projectService;
@Autowired
protected HttpServletRequest context;
protected Project project() {
// get {userName} and {projectName} path variables from request string
String[] split = context.getPathInfo().split("/");
return projectService.getProject(split[2], split[3]);
}
@RequestMapping(method = GET)
public Project get() {
return project();
}
@RequestMapping(method = GET, value = "/doSomething")
public void doSomething() {
Project project = project();
// do something with project
}
// more @RequestMapping methods using project()
}
是否可以通过注释将路径变量自动装配到控制器中,这样我就不必拆分请求路径并从project()
方法的请求字符串中获取部分内容?
答案 0 :(得分:0)
为了从请求中进行自定义绑定,您必须实现自己的HandlerMethodArgumentResolver(这是一个简单的例子,而不检查路径变量是否确实存在且它也是全局的,所以每次你尝试绑定到Project类时,都会使用这个参数解析器):
class ProjectArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(Project.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Map<String, String> uriTemplateVars = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
return getProject(uriTemplateVars.get("userName"), uriTemplateVars.get("projectName"));
}
private Project getProject(String userName, String projectName) {
// replace with your custom Project loading logic
Project project = new Project(userName, projectName);
return project;
}
}
并使用WebMvcConfigurerAdapter注册:
@Component
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new ProjectArgumentResolver());
}
}
在您的控制器中,您必须将Project作为方法参数,但不使用@PathVariable注释它:
@Controller
@RequestMapping("/projects/{userName}/{projectName}")
public class HomeController {
@RequestMapping(method = RequestMethod.GET)
public void index(Project project){
// do something
}
}