I am trying to upgrade from 5.0.2.RELEASE to 5.2.7.RELEASE.

We have some controllers laying around that accepts path variables with semicolon. For the compatibility we need these variables as full string ( aa=123;bb=456 ). Previously we had this configuration:

// OLD
@Configuration
public class CustomRequestHandlerMapping extends WebMvcConfigurationSupport {

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
        handlerMapping.setRemoveSemicolonContent(false);
        return handlerMapping;
    }
}

Now that the method signature of WebMvcConfigurationSupport.requestMappingHandlerMapping() has changed, we have been looking for alternate solutions. We have tried to extend WebMvcConfigurer:

// NEW
@Configuration
public class CustomRequestHandlerMapping implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

I have checked and saw that shouldRemoveSemicolonContent() is in fact true. But the variable is still cut off. See the controller:

@Controller
@RequestMapping("/accounts/{accountId}/items")
public class ItemController {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @RequestMapping(value = "/{itemId}", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasAnyRole('Admin', 'User')")
    public ItemDTO getItem(
        @PathVariable String accountId,
        @PathVariable String itemId) {
        System.out.println("pathVariable: " + itemId);
        System.out.println("shouldRemoveSemicolonContent: " + requestMappingHandlerMapping.getUrlPathHelper().shouldRemoveSemicolonContent());
        // ....
    }
}

Logs show that:

Request url: "/accounts/123/items/itemid=234;type=bigitem"
pathVariable: itemid=234
shouldRemoveSemicolonContent: false

But I want pathVariable to be itemid=234;type=bigitem. What am I missing and what do I need to do to achieve this?

Is there a possible bug?


Edit: If we extend UrlPathHelper with following values and use it in configurer.setUrlPathHelper(new CustomUrlPathHelper()), we get the desired result. But it really feels like a hack.

public class CustomUrlPathHelper extends UrlPathHelper {

    public DeceivingSemicolonFriendlyUrlPathHelper() {
        setRemoveSemicolonContent(false);
    }

    @Override
    public boolean shouldRemoveSemicolonContent() {
        return true;
    }
}

Comment From: rstoyanchev

I don't know if anything changed but the way to do this is:

@GetMapping("/{itemId}")
public ItemDTO getItem(
        @PathVariable String accountId,
        @PathVariable String itemId,
        @MatrixVariable("type") String type) {
   // ...
}

There are several options. Please read https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-matrix-variables.

Comment From: salemdar

I was possible to get the whole path variable as one string before, now it is not. Not at least without the hack I posted in the edit.

Comment From: rstoyanchev

Yes indeed it was possible but it is debatable whether it should have been. Is there a reason why using @MatrxVariable to access individual values or all as a Map<String, String> is not adequate?

Comment From: maxhertrampf

I ran into the same problem.

It seems like the bug is just ignored here.

UrlPathHelper.removeSemicolonContent() still exists but does not do what its documentation says. That is clearly a bug. Please either fix the code so that UrlPathHelper.removeSemicolonContent() works again or remove it if you are unable to get it to work again.