Привязать переменные пути к пользовательскому объекту модели весной

У меня есть класс, который моделирует мой запрос, что-то вроде

class Venue {
    private String city;
    private String place;

    // Respective getters and setters.
}

И я хочу поддерживать RESTful URL для получения информации о месте проведения. Итак, у меня есть метод контроллера, подобный этому.

@RequestMapping(value = "/venue/{city}/{place}", method = "GET")
public String getVenueDetails(@PathVariable("city") String city, @PathVariable("place") String place, Model model) {
    // code
}

Есть ли способ, который я могу сказать весной, чтобы связать мои переменные пути с объектом модели (в данном случае Venue) вместо получения каждого отдельного параметра?


person Senthil Babu    schedule 17.06.2013    source источник


Ответы (3)


Spring MVC предлагает возможность связывать параметры запроса и переменные пути с JavaBean, в вашем случае это Venue. Например:

@RequestMapping(value = "/venue/{city}/{place}", method = "GET")
public String getVenueDetails(Venue venue, Model model) {
    // venue object will be automatically populated with city and place
}

Обратите внимание, что ваш JavaBean должен иметь свойства city и place, чтобы он работал.

Для получения дополнительной информации вы можете взглянуть на пример withParamGroup() из spring-projects/spring-mvc-showcase

person Liang Zhou    schedule 24.04.2014
comment
Я никогда не думал, что даже переменная пути может быть автоматически помещена в bean-компонент. Любой документ об этом интересном поведении? какое у него официальное название? - person hafan96; 13.09.2020

Согласно документации Spring, доступной по адресу http://static.springsource.org/spring/docs/3.2.3.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-uri-templates, автоматическая поддержка предоставляется только для простых типов:

Аргумент @PathVariable может иметь любой простой тип, такой как int, long, Date и т. д. Spring автоматически преобразует в соответствующий тип или выдает TypeMismatchException, если это не удается сделать.

Я не пробовал эту конкретную комбинацию @RequestParam и Model, но похоже, что вы можете добиться желаемой реализации, создав собственный WebBindingInitializer, как подробно описано на http://static.springsource.org/spring/docs./3.2.3.RELEASE/spring-framework-reference/html/mvc.html#mvc-ann-typeconversion.

Пользовательский класс будет иметь доступ к WebRequest и будет возвращать объект домена, заполненный данными, извлеченными из этого запроса.

person vincentks    schedule 17.06.2013
comment
Я думаю, это было бы немного излишним для моего варианта использования. Но спасибо за предложение. - person Senthil Babu; 18.06.2013

Вы можете предоставить реализацию интерфейса HandlerMethodArgumentResolver. Этот интерфейс в основном используется для разрешения аргументов ваших методов контроллера способами, которые Spring не может (что, по сути, вы и пытаетесь сделать). Вы достигаете этого, реализуя эти два метода:

public boolean supportsParameter(MethodParameter mp) {
    ...
}

public Object resolveArgument(mp, mavc, nwr, wdbf) throws Exception {
    ...
}

Вы можете внедрить свою реализацию в контекст Spring через:

<mvc:annotation-driven>
    <mvc:argument-resolvers>
        <bean class="com.path.ImplementationOfHandlerMethodArgumentResolver"/>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

Когда Spring обнаруживает параметр, который не может разрешить, он вызывает ваш метод supportsParameter(), чтобы узнать, может ли ваш преобразователь разрешить этот параметр. Если ваш метод возвращает true, то Spring вызовет ваш метод resolveArgument() для фактического разрешения параметра. В этом методе у вас есть доступ к объекту NativeWebRequest, который вы можете использовать для получения пути за пределами contextPath. (в вашем случае это будет: /venue/{city}/{place}) вы можете проанализировать путь запроса и попытаться получить строки города/места для заполнения в вашем объекте места проведения.

person Paul Gray    schedule 14.08.2013