0

I have a project named customer written in spring boot, and another maven project named customer-customization adds the customer project as a dependency and uses it. My goal: To change the rest service. As the name of the project suggests, I want to allow the project to be used by making changes without touching my source code.

Customer project

Spring boot version : 3.2.2

Java version: 21

pom.xml

<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

CityService.java

@RequestMapping("city")
public interface CityService {

    @PostMapping(value = "/createCity", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    ResponseEntity<CityDto> createCity(@RequestBody CityDto param);

}

CityServiceImpl.java

@RestController
public class CityServiceImpl implements CityService {

    @Override
    public ResponseEntity<CityDto> createCity(CityDto param) {
        ...
    }

}

customer-customization project

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rz.customer</groupId>
    <artifactId>customer-customization</artifactId>
    <packaging>jar</packaging>
    <version>0.0.1-alpha.1</version>
    <name>Customer Customization</name>
    <properties>
        <start-class>com.rz.customer.app.CustomerCustomizationApplication</start-class>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <customer.version>0.0.1-alpha.1</customer.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>com.rz.customer</groupId>
            <artifactId>customer-app</artifactId>
            <version>${customer.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.2.2</version>
                <configuration>
                    <mainClass>com.rz.customer.app.CustomerCustomizationApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

CustomCityService.java

@RequestMapping("city")
public interface CustomCityService {

    @PostMapping(value = "/createCity", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    ResponseEntity<CustomCityDto> createCity(@RequestBody CustomCityDto param);
}

CustomCityServiceImpl.java

@RestController
public class CustomCityServiceImpl implements CustomCityService {

    @Override
    public ResponseEntity<CityDto> createCity(CustomCityDto param) {
        ...
    }

}

While running the customer-customization project I'm getting this error:

"Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'customCityServiceImpl' method 
com.rz.customer.controller.impl.CustomCityServiceImpl#createCity(CityInputDto)
to {POST [/city/createCity], consumes [application/json], produces [application/json]}: There is already 'customCityServiceImpl' bean method
com.rz.customer.controller.impl.CustomCityServiceImpl#createCity(CustomCityDto)"

I know this error is normal because there cannot be more than one service belonging to the same url.

My goal is somehow I want the customer-customization project to overwhelm the service in the customer project. I tried extending the RequestMappingHandlerMapping class but I couldn't. Is it possible to do this, perhaps by adding notation like @Primary to the CustomCityService.java class and prioritizing it, or some other way? Since my goal is to have the customer project done without touching the source code, I want to make this change in the customer-customization project.

How can I do?

1 Answer 1

0

I solved my problem with registerHandlerMethod method of the RequestMappingHandlerMapping class.

@Configuration
public class CustomRequestMappingHandlerMapping implements WebMvcRegistrations {

    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new RequestMappingHandlerMapping() {

            @Override
            protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
                Set<RequestMethod> httpMethods = mapping.getMethodsCondition().getMethods();
                if (handler.toString().equals("cityServiceImpl") && httpMethods.contains(RequestMethod.POST)
                        && mapping.getPatternValues().contains("/city/createCity")) {
                    return;
                }
                super.registerHandlerMethod(handler, method, mapping);
            }
        };
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.