Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring programmatically register RequestMapping

I have a working url as this: 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;
   }

}

and I would to register some other mappings at initializing of my application as this:

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

All these urls will return same response as localhost/info

The xxxx, yyyy part of the application is changeable. I have to register custom mappings as

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

Bu this is only working for views.

Any idea for dynamic registration?

like image 405
Cemo Avatar asked Sep 29 '26 22:09

Cemo


1 Answers

I believe that simple example is worth more than 1000 words :) In SpringBoot it will look like...

Define your controller (example health endpoint):

public class HealthController extends AbstractController {

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

}

And create your configuration:

@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;
    }

}

Regarding the handler order - take a look about the reason here: Java configuration of SimpleUrlHandlerMapping (Spring boot)

The MappingJacksonSingleView is auxiliary class in order to return single json value for model and view:

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;
    }

} 

Jackson single view source - this blog post: https://www.pascaldimassimo.com/2010/04/13/how-to-return-a-single-json-list-out-of-mappingjacksonjsonview/

Hope it helps!

like image 183
Przemek Nowak Avatar answered Oct 01 '26 17:10

Przemek Nowak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!