[英]Spring PathVariable used outside
I have Spring rest controller that provides operations on Project
entity. 我有Spring Rest控制器,可提供对Project
实体的操作。 All methods use same entity accessing code. 所有方法都使用相同的实体访问代码。 I don't want to copy&paste @PathVariable
parameters in all methods, so I've made something like this. 我不想在所有方法中都复制并粘贴@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()
}
Is it possible to autowire path variables into controller by annotation so I don't have to split request path and get parts of it from request string for project()
method? 是否可以通过注释将路径变量自动连接到控制器中,所以我不必拆分请求路径并从project()
方法的请求字符串中获取部分内容?
In order to do custom binding from request you've got to implement your own HandlerMethodArgumentResolver (it's a trivial example without checking if path variables actually exist and it's also global, so every time you will try to bind to Project class this argument resolver will be used): 为了从请求中进行自定义绑定,您必须实现自己的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;
}
}
and register it using WebMvcConfigurerAdapter : 并使用WebMvcConfigurerAdapter进行注册:
@Component
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new ProjectArgumentResolver());
}
}
In your controller you have to put Project as a method argument, but do not annotate it with @PathVariable: 在你的控制器,你必须把项目作为方法的参数,但不 @PathVariable标注为:
@Controller
@RequestMapping("/projects/{userName}/{projectName}")
public class HomeController {
@RequestMapping(method = RequestMethod.GET)
public void index(Project project){
// do something
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.