Подтвердить что ты не робот

Spring Контроллер MVC перенаправляет параметры URL вместо ответа

Я пытаюсь внедрить URL-адреса RESTful в моем приложении Spring MVC. Все хорошо, за исключением обработки форм. Мне нужно перенаправить либо обратно в исходную форму, либо на страницу "Успех".

@Controller
@RequestMapping("/form")
public class MyController {

    @RequestMapping(method = RequestMethod.GET)
    public String setupForm() {
        // do my stuff
        return "myform";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processForm(ModelMap model) {            
        // process form data

        model.addAttribute("notification", "Successfully did it!");
        return "redirect:/form";
    }
}

Однако, как я читал в Spring документации, при перенаправлении любые параметры будут помещены в URL-адрес. И это не работает для меня. Каким будет самый изящный способ этого?

4b9b3361

Ответ 1

http://jira.springframework.org/browse/SPR-6464 предоставил мне то, что мне нужно, чтобы все работало до тех пор, пока Spring MVC не предложит функциональность (возможно, в 3.0.2 выпуск). Хотя я просто реализовал классы, которые они временно использовали, и добавил фильтр в мой контекст веб-приложения. Отлично работает!

Ответ 2

У меня была та же проблема. решил это следующим образом:

return new ModelAndView("redirect:/user/list?success=true");

И тогда мой метод контроллера выглядит следующим образом:

public ModelMap list(@RequestParam(required=false) boolean success) {
    ModelMap mm = new ModelMap();
    mm.put(SEARCH_MODEL_KEY, campaignService.listAllCampaigns());
    if(success)
        mm.put("successMessageKey", "campaign.form.msg.success");
    return mm;
}

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

Ответ 3

Эта проблема вызвана (как утверждали другие) атрибуты модели, которые сохраняются в строке запроса - это обычно нежелательно и может создавать уязвимости безопасности, а также смешные строки запросов. Мое обычное решение - никогда не использовать Strings для перенаправления в Spring MVC, вместо этого используйте RedirectView, который может быть настроен не для отображения атрибутов модели (см. http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/view/RedirectView.html)

RedirectView(String url, boolean contextRelative, boolean http10Compatible, boolean exposeModelAttributes)

Итак, я имею тенденцию использовать метод утилиты, который выполняет "безопасное перенаправление":

public static RedirectView safeRedirect(String url) {
    RedirectView rv = new RedirectView(url);
    rv.setExposeModelAttributes(false);
    return rv;
}

Другой вариант - использовать bean конфигурацию XML:

<bean id="myBean" class="org.springframework.web.servlet.view.RedirectView">
   <property name="exposeModelAttributes" value="false" />
   <property name="url" value="/myRedirect"/>
</bean>

Опять же, вы можете абстрагировать это в свой класс, чтобы избежать повторения (например, SafeRedirectView).


Заметка об "очищении модели" - это не то же самое, что "не подвергать модель" при любых обстоятельствах. На одном сайте, на котором я работал, было много фильтров, которые добавили вещи в модель, это означало, что очистка модели до перенаправления не помешала бы длинной строке запроса. Я бы также предположил, что "не подвергать атрибутам модели" более семантический подход, чем "очистка модели перед перенаправлением".

Ответ 4

Вместо processForm() можно вернуть объект View и вернуть ему конкретный тип RedirectView, у которого есть параметр для setExposeModelAttributes().

Когда вы возвращаете имя представления с префиксом "redirect:", Spring MVC превращает это в объект RedirectView в любом случае, он просто делает это с setExposeModelAttributes в true (что, по моему мнению, является нечетным значением по умолчанию,).

Ответ 5

Если вам не требуется сообщение об успешности в URL-адресе, тогда один параметр должен поместить его в сеанс (в методе processForm), а затем проверить его (и удалить) в методе setupForm.

Отредактировано для добавления: если это больно делать вручную, вы можете написать подкласс RedirectView, который добавляет атрибут "сообщение" и переносит процесс вставки его в сеанс. Не уверен, однако, если есть простой способ обернуть вывод сообщения из сеанса...

Честно говоря, я не думаю, что есть простой ответ - природа перенаправления HTTP заключается в том, что состояние не переносится; если вы хотите сохранить состояние в любом случае, вы застряли с различными обычными способами поддержания состояния в веб-приложениях: сеанс, куки файл, запрос...

Ответ 6

Эй, вы можете просто сделать одну простую вещь вместо того, чтобы использовать модель для отправки параметра, использовать объект HttpServletRequest и сделать это

HttpServletRequest request;
request.setAttribute("param", "value")

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

Ответ 7

@RequestMapping(path="/apps/add", method=RequestMethod.POST)
public String addApps(String appUrl, Model model, final RedirectAttributes redirectAttrs) {
    if (!validate(appUrl)) {
       redirectAttrs.addFlashAttribute("error", "Validation failed");
    }
    return "redirect:/apps/add"
} 

@RequestMapping(path="/apps/add", method=RequestMethod.GET)
public String addAppss(Model model) {
    String error = model.asMap().get("error");
}