Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accepting a Spring Data REST URI in custom controller

I have a Spring Data Rest webmvc application that I'd like to add some custom functionality to for batch operations.

I've created a controller, and blended it into the uri namespace, but I'd like for it to be able to accept URI's like the custom /search queries do, rather than simply an ID.

I have tried registering a custom <String, Long> converter (my entity has a Long ID type, but that seems to get ignored. Is there any way to configure my controller such that it adopts that behavior from the auto-implemented SDR controllers?

Even if there is some sort of method I can call that will auto-resolve a URI to an entity, that would work just as well (as I can then simply accept a String in my controller)

Here's where I'm at.

@Configuration
public class CustomWebConfiguration extends WebMvcConfigurationSupport {

    //irrelevant code omitted

    @Bean
    public DomainClassConverter<?> domainClassConverter() {
        DomainClassConverter<FormattingConversionService> dc = new DomainClassConverter<FormattingConversionService>(mvcConversionService());
        return dc;
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
          registry.addConverter(String.class, Long.class, testConverter());
    }

    @Bean 
    Converter<String, Long> testConverter() {
        return new Converter<String, Long>() {

            @Override
            public Long convert(String source) {
                //this code does _not_ get run at any point
                if (source.indexOf('/') == -1) { return Long.parseLong(source); }

                source = source.substring(source.lastIndexOf('/') + 1);
                Long id = Long.parseLong(source);

                return id;
            }   
        };
    }
}

SDR Config

@Configuration
@EnableHypermediaSupport(type = { HypermediaType.HAL })
public class CustomRestConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    public RepositoryRestConfiguration config() {
      RepositoryRestConfiguration config = super.config();
      config.setBasePath("/api");
      config.exposeIdsFor(ApplicationMembership.class);
      return config;
    }


}

And my (contrived) controller:

ApplicationType is one of my entities that are correctly managed by SDR/repository magic

@BasePathAwareController
@RepositoryRestController
@RequestMapping("applications/special")
public class ApplicationExtensionController {
    @RequestMapping("a")
    public ResponseEntity<?> reply(@RequestParam("type") ApplicationType type) {
        return new ResponseEntity<String>(type.getIcon(), HttpStatus.OK);
    }
}

I've looked around quite a bit but can't quite manage to make anything work. When I create a <String, ApplicationType> converter that utilizes the repository, it also does not get called, as the DomainClassConverter just calls its underlying <String, Long> converter (which obviously fails, as it cannot correctly parse out types/1 into a long.

Appreciate the help!

Forgot to mention

  • Spring Data Rest 2.4.0
  • Spring HATEOAS 0.19.0
  • Spring 4.2.1

Using JPA repositories

like image 402
CollinD Avatar asked Sep 10 '15 23:09

CollinD


People also ask

Does the uricomponentsbuilder come with the Spring-Web jar?

So, it all depends on which version of Spring you're using. If you're using an old version of Spring, the UriComponentsBuilder with your spring-web jar wont be included. For more information on standard URI 's and encoding click on this link: Java URL Encoding. Delving into URI 's can get quite complex with Rest Template.

What is spring data rest?

1. Introduction Spring Data REST can remove a lot of boilerplate that's natural to REST services. In this tutorial, we'll explore how to customize some of Spring Data REST's HTTP binding defaults. 2. Spring Data REST Repository Fundamentals

What is the Uri package used for in Spring Framework?

org.springframework.web.client.ResourceAccessException: I/O error: http://localhost:8080%api%users Regardless of all the research, the URI package comes in quite handy with String Builder to Query a API. There are a few ways of implementing this:

Is it possible to hardcode a URI endpoint for rest template interface?

Hard coding a URI endpoint for the Rest template interface is preferably the first point of reference when implementing a micro service or a monolith application. There is no easy way to do this!


1 Answers

As it turns out, I was on the right track with adding a converter, unfortunately I was doing it in the wrong configuration method.

I was able to get the desired functionality by moving my testConverter() bean to the RepositoryRestMvcConfiguration extension config class and then adding

@Override
public void configureConversionService(ConfigurableConversionService service) {
    service.addConverter(testConverter());
}

And working as intended. I feel a bit silly now for throwing that in the wrong spot in the first place, but hopefully this will help someone else out!

like image 94
CollinD Avatar answered Sep 18 '22 15:09

CollinD