RequestMapping с слешами и точкой

Я должен поддерживать следующий формат URL

/service/country/city/addr1/addr2/xyz.atom /service/country/city/addr1/addr2/addr3/xyz.atom

здесь country и city можно сопоставить с @PathVariable но после этого путь может быть динамическим с несколькими косыми чертами. Конечная часть будет иметь .atom или аналогичные.

Я попытался следовать, но ни один из вариантов не кажется работа

  • подстановочные

    @RequestMapping(value="/service/{country}/{city}/**")

  • выражение

    @RequestMapping(value="/service/{country}/{city}/{addr:.+}")

  • UseSuffixPatternMatch


    переопределить метод в классе Config

     @Override
     public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
     }
    

похоже, комбинация косой черты и точек не работает с вышеуказанными решениями. Я продолжаю получать 406 для несоответствующего заголовка Accept или 404

2 ответов


наиболее динамичным подходом было бы использовать MatrixVariable для управления списком адресов, но он не применим в вашем контексте, так как пути не могут быть изменены, насколько я понимаю из вашего вопроса.

лучшее, что вы можете сделать для управления динамическим путем, - это выполнить два шага:

  1. поставил RequestMapping который извлекает все данные, кроме адресов
  2. извлеките адреса вручную в методе

так для первым шагом у вас будет что-то вроде этого:

    @RequestMapping(value="/service/{country}/{city}/**/{file}.atom")
    public String service(@PathVariable String country, 
         @PathVariable String city, @PathVariable String file,
         HttpServletRequest request, Model model) { 

это сопоставление соответствует всем необходимым путям и позволяет извлечь страну, город и имя файла.

на втором шаге мы будем использовать то, что было извлечено, чтобы получить адреса, делая что-то вроде этого:

String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
path = path.substring(String.format("/service/%s/%s/", country, city).length(), 
                      path.length() - String.format("%s.atom", file).length());
String[] addrs = path.split("/");
  1. Сначала мы извлекаем из запроса полный путь
  2. затем мы удаляем то, что мы уже извлекли, которые здесь являются началом и конец пути
  3. затем, наконец, мы используем String.split извлечь все адреса

на этом уровне у вас есть все необходимое.


вы можете попробовать это,

@RequestMapping(value="/service/{country}/{city}/{addr:[a-z]+\\.(atom|otherExtensions)}")

просто нужно указать полный формат регулярных выражений, в котором вы ожидаете расширение в конце url, такого как atom, так как это будет интерпретироваться по умолчанию как MediaType весной.

другое решение-указать принятые MediaTypes

@RequestMapping(value="/service/{country}/{city}/{addr}", consumes = {MediaType.ATOM, MediaType...})

вы можете создавать пользовательские MediaTypes, если он не предопределен весной.