3

我有一个这样的工作网址:localhost/info

@Controller
@RequestMapping("/info")
public class VersionController {

   @RequestMapping(value = "", method = RequestMethod.GET)
   public @ResponseBody
   Map get() {
      loadProperties();
      Map<String, String> m = new HashMap<String, String>();
      m.put("buildTimestamp", properties.getProperty("Application-Build-Timestamp"));
      m.put("version", properties.getProperty("Application-Version"));
      return m;
   }

}

我会在初始化我的应用程序时注册一些其他映射,如下所示:

localhost/xxxx/info
localhost/yyyy/info
localhost/zzzz/info

所有这些 url 将返回相同的响应localhost/info

应用程序的 xxxx、yyyy 部分是可变的。我必须将自定义映射注册为

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("???").setViewName("???");
}

但这仅适用于视图。

动态注册的任何想法?

4

6 回答 6

4

您可以注册一个新的HandlerMapping,您可以在其中为您的 URL 路径添加处理程序;最方便的实现是SimpleUrlHandlerMapping

如果您希望这些处理程序是 bean 方法(如用 注释的那些@RequestMapping),您应该将它们定义为HandlerMethod包装器,以便已经注册的RequestMappingHandlerAdapter将调用它们。

于 2013-03-19T13:26:57.580 回答
4

从 Spring 开始5.0.M2,Spring 提供了一个功能性 Web 框架,允许您以编程方式创建类似“控制器”的构造。

在您的情况下,您需要做的是为您需要处理的 URL 创建一个适当的RouterFunction,然后使用适当的HandlerFunction简单地处理请求。

但是请记住,这些构造不是 Spring MVC 的一部分,而是 Spring Reactive 的一部分。

查看这篇博文了解更多详情

于 2016-09-26T14:17:45.067 回答
3

我相信这个简单的例子值得超过 1000 字:) 在 SpringBoot 中它看起来像......

定义您的控制器(示例健康端点):

public class HealthController extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) {
        return new ModelAndView(new MappingJacksonSingleView(), "health", Health.up().build());
    }

}

并创建您的配置:

@Configuration
public class CustomHealthConfig {

    @Bean
    public HealthController healthController() {
        return new HealthController();
    }

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        mapping.setOrder(Integer.MAX_VALUE - 2);
        mapping.setUrlMap(ImmutableMap.of("/health", healthController()));
        return mapping;
    }

}

关于处理程序顺序 - 看看这里的原因:SimpleUrlHandlerMapping的Java配置(Spring boot)

MappingJacksonSingleView为了返回模型和视图的单个 json 值的辅助类:

public class MappingJacksonSingleView extends MappingJackson2JsonView {

    @Override
    @SuppressWarnings("unchecked")
    protected Object filterModel(Map<String, Object> model) {
        Object result = super.filterModel(model);
        if (!(result instanceof Map)) {
            return result;
        }

        Map map = (Map) result;
        if (map.size() == 1) {
            return map.values().toArray()[0];
        }
        return map;
    }

} 

杰克逊单视图源 - 这篇博文:https ://www.pascaldimassimo.com/2010/04/13/how-to-return-a-single-json-list-out-of-mappingjacksonjsonview/

希望能帮助到你!

于 2019-02-13T19:43:48.737 回答
1

(现在)可以通过RequestMappingHandlerMapping.registerMapping()方法注册请求映射。

例子:

@Autowired
RequestMappingHandlerMapping requestMappingHandlerMapping;

public void register(MyController myController) throws Exception {
    RequestMappingInfo mappingInfo = RequestMappingInfo.paths("xxxx/info").methods(RequestMethod.GET).build();
    Method method = myController.getClass().getMethod("info");
    requestMappingHandlerMapping.registerMapping(mappingInfo, myController, method);
}


于 2020-05-10T09:53:06.570 回答
0

您可以通过扩展RequestMappingHandlerMapping来注册自己的 HandlerMapping ,例如覆盖registerHandlerMethod.

于 2016-01-05T16:38:22.830 回答
-5

目前尚不清楚您要实现的目标,但也许您可以在@RequestMapping 中使用@PathVariable,例如:

@RequestMapping("/affId/{id}")
public void myMethod(@PathVariable("id") String id) {}

编辑:原始示例已更改它的出现,但您可能仍然可以使用 PathVariable。

于 2013-03-19T13:28:45.563 回答