当前位置: 首页 > 知识库问答 >
问题:

java - spring如何动态注册控制器的路由?

和弘博
2024-09-07

我这段代码可以生效,但是有个问题,不是动态化的。
参数类型我得写UserDto.class,我想动态化,我不知道参数类型到底是什么。

package dry.example.service.impl;

import dry.example.route.CustomInvocationHandler;
import dry.example.route.RouteAdmin;
import dry.example.route.UserDto;
import dry.example.service.RouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@Service
public class RouteServiceImpl implements RouteService {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    public void run(Object handler) {
        try {
            RequestMappingInfo requestMappingInfo = RequestMappingInfo.paths("testing").methods(RequestMethod.GET).build();
            Method method = handler.getClass().getMethod("h01", UserDto.class);
            requestMappingHandlerMapping.registerMapping(requestMappingInfo, handler, method);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

共有1个答案

伊羽
2024-09-07

在Spring中动态注册控制器的路由并处理未知参数类型的问题,可以通过使用Java的反射和泛型技术来解决。然而,由于RequestMappingHandlerMappingregisterMapping方法要求具体的参数类型,你需要在运行时确定这些类型。

一个可行的解决方案是,如果你确实需要动态地处理不同类型的参数,你可以创建一个通用的接口或方法签名,该方法使用泛型或者统一的HttpServletRequest/HttpServletResponse参数(尽管这可能不是最优雅的方式,因为它限制了Spring MVC的自动绑定和验证功能)。

但是,如果你想要更灵活地处理不同的DTO(数据传输对象)类型,你可以考虑以下策略:

  1. 使用泛型方法:在你的处理器接口或类中定义一个泛型方法,并在运行时动态地确定具体的类型。然而,这通常涉及到更复杂的反射逻辑,因为Method对象需要在编译时确定其参数类型。
  2. 使用HttpServletRequest作为参数:虽然这限制了自动参数绑定,但你可以从请求体中读取原始数据,并手动解析为所需的DTO类型。
  3. 动态代理:创建一个动态代理,该代理可以捕获所有请求,并基于请求的路径或头信息来决定使用哪个具体的处理器方法。这种方法较为复杂,但提供了高度的灵活性和控制。
  4. 使用Spring MVC的扩展点:考虑使用Spring MVC的HandlerMethodArgumentResolverHandlerMethodReturnValueHandler接口来更细粒度地控制参数解析和返回值处理。

对于你当前的代码,如果你想动态地处理不同的UserDto或类似的DTO类型,你可能需要在调用registerMapping之前,通过某种机制(如配置或注解)来确定具体的类型。然而,这通常意味着你需要编写额外的逻辑来解析这些配置或注解,并将其转换为Method对象所需的类型。

如果你的目标是简单地支持多种DTO类型而不需要在运行时频繁更改,你可能需要为每种类型编写一个具体的处理器方法,并在注册时指定这些方法。

最后,如果你的应用确实需要高度动态地处理路由和参数类型,并且这些需求在运行时频繁变化,那么可能需要考虑使用更灵活的架构,如微服务或使用消息队列来解耦服务的不同部分。这样,你可以为每个服务或消息类型编写专门的处理器,而不是试图在一个大型应用中动态地处理所有可能的情况。

 类似资料:
  • 问题内容: 我仍然是Angularjs的新手。我想在控制器中动态注入服务(我创建的)的依赖项。 但是,当我对具有依赖项的服务进行编码时,出现此错误: 错误:未知提供程序:$ windowProvider <-$ window <-base64 这是控制器的代码。 此代码有效: 此代码不起作用: 另一个问题是服务与控制器位于同一模块中。如果模块具有依赖项,则无法使用(我的模块配置中具有$ route

  • 问题内容: 我试图在我的应用程序中编写通用路由,并根据路由参数动态解析视图和控制器名称。 我有以下有效的代码: 但是,我无法找到一种动态解析控制器名称的方法。我尝试使用此处所述的方法,但是ui- router似乎处理处理的方式与angular- route不同。 有指针吗? 编辑 :我已经尝试使用,但是对我不起作用(例如,以下代码仅返回一个硬编码的控制器名称,以测试其是否真正起作用): 给我以下错

  • 我正在intellij中运行Spring Boot应用程序,我所有的计划任务和一切都正常工作,但是我在@RestController和@Request estMap注册的控制器没有注册。当我尝试访问这些时,我得到404,而当我使用eclipse时,同样工作正常。甚至我的ide控制台也显示rest控制器已注册: 无法猜测可能会出什么问题?

  • 我对Spring框架是完全陌生的。我有一个任务是在Spring上制作电话簿应用程序。我需要登记和授权,还有我的电话簿。我有两个控制器,第一个是控制授权和注册的UserController 当我尝试进行身份验证或注册时。新用户我有这样的错误: NestedServletException:请求处理失败;嵌套异常是java.lang.IllegalStateException:映射到HTTP路径“HT

  • 问题内容: 是否可以基于路由组动态加载控制器,js文件和模板?伪代码不起作用: 我已经看到了很多这样的问题,但是没有一个问题基于路由组加载js文件/控制器。 问题答案: 我设法解决了受@ calebboyd,http : //ify.io/lazy-loading-in-angularjs/ 和http://weblogs.asp.net/dwahlin/archive/2013/05/22/dy

  • 问题内容: 运行期间是否可以注入示波器或控制器?或任何其他建议将服务动态注入控制器? 提前致谢 问题答案: 可以使用$ injector 将服务动态(按名称)注入到控制器中。能够通过控制器参数注入服务只是Angular提供的一种便利。在后台,Angular使用$ injector来检索对象实例。但是我们也可以自己使用$ injector。 小提琴。