Spring PathVariable在外面使用

时间:2014-11-17 18:19:11

标签: java spring spring-mvc controller annotations

我有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()方法的请求字符串中获取部分内容?

1 个答案:

答案 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
    }
}