1

I want to create different instances of Spring RestController with different instances of beans (service, dao, cache) injected.

Currently, we have implemented this with JAX-RS Restful API.

But when I try to implement the same in Spring RestController, I'm getting below error when Spring tries to create a new bean "product2RestController".

Because bean "product1RestController" is already mapped to the rest url and created.

Stacktrace:

Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'product2RestController' method

@Path("/products")
public class ProductLookupRestService {

    @Context
    HttpServletRequest httpServletRequest;

    @Context
    HttpServletResponse httpServletResponse;

    @Context
    UriInfo uriInfo;

    private Map<Integer, AbstractProductRestService> productServiceLoopup;

    public void setProductServiceLoopup(Map<Integer, AbstractProductRestService> productServiceLoopup) {
        this.productServiceLoopup = productServiceLoopup;
    }

    @Path("/{productId}")
    public AbstractProductRestService getReport(@PathParam("productId") int productId) {
        AbstractProductRestService productRestService = this.productServiceLoopup.get(productId);
        productRestService.setHttpServletRequest(httpServletRequest);
        productRestService.setHttpServletResponse(httpServletResponse);
        productRestService.setUriInfo(uriInfo);

        return productRestService;
    }
}

public abstract class AbstractProductRestService {

    @Context
    protected HttpServletRequest httpServletRequest;

    @Context
    protected HttpServletResponse httpServletResponse;

    @Context
    protected UriInfo uriInfo;

    protected IProductService productService;
    protected IProductCache productCache;

    public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
        this.httpServletRequest = httpServletRequest;
    }

    public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
        this.httpServletResponse = httpServletResponse;
    }

    public void setUriInfo(UriInfo uriInfo) {
        this.uriInfo = uriInfo;
    }

    public void setProductService(IProductService productService) {
        this.productService = productService;
    }

    public void setProductCache(IProductCache productCache) {
        this.productCache = productCache;
    }

    @POST
    @Path("/filters")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response createFilters(Form filterForm) {
        //Save the filters and return uuid
        ResponseBuilder responseBuilder = Response.created(uriInfo.getAbsolutePathBuilder().path("uuid").build());

        return responseBuilder.build();
    }
}

public class ProductRestService extends AbstractProductRestService {

    @GET
    @Path("/filters/{uuid}/detail")
    public String getProductDetail(){
        // do cache check : productCache
        return this.productService.readProductDetail();
    }
}

public class ProductServiceImpl implements IProductService{

    @Override
    public String readProductDetail() {
        // Call to dao to get the data
        return null;
    }

}

<bean id="product1RestService" class="com.poc.jaxrs.rest.ProductRestService">
        <property name="productService" ref="product1Service"/>
        <property name="productCache" ref="product1Cache"/>
    </bean>

    <bean id="product2RestService" class="com.poc.jaxrs.rest.ProductRestService">
        <property name="productService" ref="product2Service"/>
        <property name="productCache" ref="product2Cache"/>
    </bean>

    <bean id="restProductLookupService" class="com.poc.jaxrs.rest.ProductLookupRestService">
        <property name="productServiceLoopup">
            <map key-type="java.lang.Integer">
                <entry key="1"><ref bean="product1RestService"/></entry>
                <entry key="2"><ref bean="product2RestService"/></entry>
            </map>
        </property>
    </bean>

I use below like urls to invoke service.

POST Call: http://localhost:8080/productservice/products/1/filters

GET Call: http://localhost:8080/productservice/products/1/filters/uuid/detail

In my spring application context xml, I'm creating multiple instances of ProductRestService class with different beans (service, cache) instances injected.

Same way I want to create multiple instances of Spring RestController, But I'm getting Ambiguous mapping error.

Thanks for your help in advance.

3
  • Can you add some code to explain better what you're trying to do...two controllers on the same class level url mapping doesn't sound possible but perhaps you can use method mappings only to avoid this clash. Commented Oct 22, 2017 at 17:17
  • I have added some sample existing code. Thanks. Commented Oct 22, 2017 at 20:33
  • Hi @AidanMoriarty, please let me know if you have any suggestion on this post. I added some code to explain. Thanks. Commented Jan 10, 2018 at 20:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.