2016-04-15 56 views
1

我知道你可以綁定得到請求參數就像一個POJO:彈簧安置 - 結合GET參數嵌套對象

@RequestMapping(value = "/reservation", 
     method = RequestMethod.GET, 
     produces = MediaType.APPLICATION_JSON_VALUE) 
public List<Reservation> loadReservations(ReservationCriteria criteria) 

    return service.loadReservations(criteria); 
} 

使用POJO,如:

public class ReservationCriteria { 
    String hotelName; 

    DateRange reservationDateRange; 
    //getters-setters omitted 
} 

與請求:/預約?hotelName = myHotel

myHotel將在ReservationCriteria對象中綁定到hotelName。

但我怎樣才能將參數綁定到嵌套的對象DateRange?其定義如下:

public class DateRange { 
    Date from; 
    Date to; 

    //getters-setters omitted 
} 

是否有允許那樣的結合就像一個URL模式:

/reservation?hotelName=myHotel&reservationDateRange={fromDate=14.04.2016,toDate=15.04.2016} 

還是我必須要申報單獨的請求參數和手動綁定呢?

@RequestMapping(value = "/reservation", 
     method = RequestMethod.GET, 
     produces = MediaType.APPLICATION_JSON_VALUE) 
public List<Reservation> loadReservations(
    ReservationCriteria criteria, 
    @RequestParam Date from, 
    @RequestParam Date to) 

    DateRange range = new DateRange(); 
    range.setFrom(from); 
    range.setTo(to); 

    criteria.setDateRange(range); 

    return service.loadReservations(criteria); 
} 

我寧願不修改ReservationCriteria類,因爲它在許多其他項目,這將導致進行重構的很多應用。

回答

2

當您將POJO作爲數據容器傳遞時,Spring使用屬性的名稱來構建查詢字符串,並使用傳遞的數據通過專用轉換器構建pojo。這適用於平面pojo或換句話說沒有嵌套,爲此你已經提供了你的轉換器。因爲這個原因,你冷有一個思考如下圖所示:

public class ReservationCriteria { 
    String hotelName; 

    Date from; 
    Date to; 
    //getters-setters omitted 
} 

@RequestMapping(value = "/reservation", 
     method = RequestMethod.GET, 
     produces = MediaType.APPLICATION_JSON_VALUE) 
public List<Reservation> loadReservations(ReservationCriteria criteria) 

    return service.loadReservations(criteria); 
} 

/預約hotelName =值&從= VAL &爲= VAL

這樣你可以用SpringMVC受益標準轉換的?

您嘗試使用某種json編碼內部對象不起作用,因爲默認情況下查詢字符串中的Spring不理解此演示文稿,因此您爲此提供了一個轉換器。

更新answare到本評論:

如果你想實現你有一個自定義轉換器實現org.springframework.core.convert.converter.Converter<S, T>然後註冊於Spring轉換服務的新的轉換器。

XML的配置,你可以使用FormattingConversionServiceFactoryBean並將其註冊MVC的命名空間象下面這樣:

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> 

    <mvc:annotation-driven conversion-service="conversionService"/> 

    <context:component-scan base-package="com.springapp.mvc"/> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/pages/"/> 
     <property name="suffix" value=".jsp"/> 
    </bean> 


    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> 
     <property name="converters"> 
      <util:list> 
       <bean class="com.springapp.mvc.DateRangeToStringConverter"/> 
       <bean class="com.springapp.mvc.StringToDateRangeConverter"/> 
      </util:list> 
     </property> 
    </bean> 
</beans> 

Java的配置,你可以擴展WebMvcConfigurerAdapter並添加你笨啊象下面這樣:

@Configuration 
@EnableWebMvc 
public class YourWebConfigurationClass extends WebMvcConfigurerAdapter{ 

    @Override 
    public void addFormatters(FormatterRegistry formatterRegistry) { 
     formatterRegistry.addConverter(yourConverter()); 
    } 

    ... 

} 

的你轉換器可以如下所示:

public class DateRangeToStringConverter implements Converter<DateRange,String> { 

    @Override 
    public String convert(DateRange dateRange) { 
     return Json.createObjectBuilder().add("fromDate",DateFormatData.DATE_FORMAT.format(dateRange.getFrom())) 
       .add("toDate", DateFormatData.DATE_FORMAT.format(dateRange.getTo())) 
       .build() 
       .toString(); 
    } 

} 



public class StringToDateRangeConverter implements Converter<String,DateRange> { 


    @Override 
    public DateRange convert(String dateRange) { 
     DateRange range = new DateRange(); 
     JsonObject jsonObject = Json.createReader(new StringReader(dateRange)).readObject(); 

     try { 
      range.setFrom(DateFormatData.DATE_FORMAT.parse(jsonObject.getString("fromDate"))); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 
     try { 
      range.setTo(DateFormatData.DATE_FORMAT.parse(jsonObject.getString("toDate"))); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 

     System.out.println(range); 
     return range; 
    } 

} 

這樣你就可以在url上列出:http://localhost:8080/reservation?hotelName=myHotel&reservationDateRange={"fromDate":"14.04.2016","toDate":"15.04.2016"}

請在預訂DateRange字段時付款,因爲我把它編碼爲json。

我希望它可以幫助你

+0

我寧願因爲它在許多其他項目,這將導致進行重構的很多使用不編輯ReservationCriteria類。 – Reek

+0

如果您的預訂不改變ReservationCriteria,您應該只提供一個Converter並註冊它。 –

+0

可否請您詳細說明如何提供轉換器? – benaich