Ответ Ajax не работает с Spring Webflow

Я пытаюсь создать приложение, используя jQuery Ajax и Spring WebFlow. Я могу отправить значение контроллеру, но не получаю всю страницу в качестве ответа вместо конкретного <script>

Вызов Ajax с помощью jquery

$.ajax({
    type:"POST",
    data:country,
    url:$("#welcomeForm").attr("action")+"&_eventId_country&ajaxSource_country"+"&countryName="+country,
    success:function(states){
        console.log(states);
    }
});

Flow.xml:

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/webflow" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<var class="com.model.Welcome" name="welcome"/>
<on-start>
<evaluate expression="springWebFlow.countryList()" result="flowScope.countries"/>
</on-start>
<view-state id="welcome" model="welcome" redirect="false" view="/WEB-INF/views/welcome.jsp">
<transition on="country" bind="false">
<evaluate expression="springWebFlow.stateList(flowRequestContext)" result="flowScope.states" result-type=""/>
</transition>
<transition on="welcome" to="actionState1"/>
</view-state>
<end-state commit="false" id="actionState1" view="/WEB-INF/views/myDetails.jsp"/>
</flow>

Контроллер:

public @ResponseBody List<State> stateList(RequestControlContext context)  throws Exception {
    List<State> states= new ArrayList<State>() ;
    State stateName= new State();
    String countryName= context.getRequestParameters().get("countryName");
    if(countryName.equals("India")){
        stateName.setStateName("Delhi");
        states.add(stateName);
    }
     return states;
}

Я не хочу использовать Spring JavaScript и не использовать Tiles. Я могу отправить запрос контроллеру, но не могу получить ответ (получив всю страницу) или показать ответ на странице.


person Vaskar Ray Karmakar    schedule 25.01.2014    source источник
comment
Если вы получаете в ответ целую страницу, похоже, вы вызываете неправильный метод контроллера. Вы пробовали отлаживать? Также что такое stateS, какая-то переменная класса? Для чего нужен states как в коде JavaScript, так и в коде Java? На контроллере он нигде не сохраняется, а в вызове AJAX вы предупреждаете переменную, не определенную в функции.   -  person t0mppa    schedule 26.01.2014
comment
Можете ли вы опубликовать полный ответ страницы, который вы получили, и опубликованный URL-адрес?   -  person Angular University    schedule 01.02.2014
comment
это просто html страница   -  person Vaskar Ray Karmakar    schedule 03.02.2014


Ответы (1)


В WebMvcConfig убедитесь, что вы правильно настроили AjaxThymeLeafViewResolver. Имя компонента должно быть указано как ТОЧНО @Bean(name = "thymeleafViewResolver").

Почему? Ну, я думаю, не называя bean-компонент AjaxThymeleafViewResolver, имя bean-компонента по умолчанию просто ajaxThymeleafViewResolver или что-то в этом роде, тогда как Spring заботится только о bean-компоненте с именем thymeleafViewResolver, похожем на интерфейсы и конкретные реализации. Например, вы говорите Spring, что мы хотим настроить thymeleafViewResolver как экземпляр AjaxThymeleafViewResolver, чтобы обеспечить специализированную обработку ajax для частичных фрагментов.

Вот мой конфиг. Это действительно тонкая деталь, и ее можно найти в одном из руководств mvc по тимелеафу.

<bean id="thymeleafViewResolver" class="org.thymeleaf.spring4.view.AjaxThymeleafViewResolver">
    <property name="viewClass" value="org.thymeleaf.spring4.view.FlowAjaxThymeleafView" />
    <property name="templateEngine" ref="templateEngine" />
</bean>

http://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#spring-webflow-integration

Отображение этого xml в java с использованием весенней загрузки приведено ниже.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private WebFlowConfig webFlowConfig;

    @Autowired
    private SpringTemplateEngine springTemplateEngine;

    @Bean
    public FlowHandlerMapping flowHandlerMapping() {
        FlowHandlerMapping handlerMapping = new FlowHandlerMapping();
        handlerMapping.setOrder(-1);
        handlerMapping.setFlowRegistry(webFlowConfig.flowRegistry());
        return handlerMapping;
    }

    @Bean
    public FlowHandlerAdapter flowHandlerAdapter() {
        FlowHandlerAdapter handlerAdapter = new FlowHandlerAdapter();
        handlerAdapter.setFlowExecutor(webFlowConfig.flowExecutor());
        handlerAdapter.setSaveOutputToFlashScopeOnRedirect(true);
        return handlerAdapter;
    }

    @Bean(name = "thymeleafViewResolver")
    public AjaxThymeleafViewResolver ajaxThymeleafViewResolver() {
        AjaxThymeleafViewResolver viewResolver = new AjaxThymeleafViewResolver();
        viewResolver.setViewClass(FlowAjaxThymeleafView.class);
        viewResolver.setTemplateEngine(springTemplateEngine);
        return viewResolver;
    }
}

Следующее, что вам нужно знать, это как понимать <render fragments=...>, поскольку документация не ясна, IMO.

<view-state id="detail" view="bookingDetail" model="hotel">
    <transition on="updateData">
        <render fragments="hoteldata"/>
    </transition>
</view-state> 

К чему на самом деле относится hotelData? Посмотрите на разметку html тимелеафа.

<div th:fragment="hotelData">
  <h1 th:text="|The price is ${hotel.price}|">
</div>

В нем говорится, что когда вы отправляете ajax-сообщение в конечную точку весеннего веб-потока flowExecutionUrl, предоставляя _eventId=updateData как 1 из сериализованных полей формы и т. д., весенний веб-поток будет отправлять только разметку html для фрагмента hotelData выше с предположительно новой ценой отеля, которая доступны через привязку модели hotel.

Профессиональный совет:

Будьте очень осторожны с опциями проверки и привязки. Стоит поиграть с ними, если до этого момента у вас ничего не работало. Например, если вы установите для привязки значение false, никакие поля формы, отправленные в запросе ajax, не будут привязаны к модели hotel, указанной в состоянии представления flow.xml, как указано выше.

transition on="updateData" validate=true | false 
transition on="updateData" bind=true | false
person reversebind    schedule 21.02.2018