我知道您可以将get请求参数绑定到像这样的pojo:
@RequestMapping(value = "/reservation",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public List<Reservation> loadReservations(ReservationCriteria criteria)
return service.loadReservations(criteria);
}
Run Code Online (Sandbox Code Playgroud)
使用像这样的pojo:
public class ReservationCriteria {
String hotelName;
DateRange reservationDateRange;
//getters-setters omitted
}
Run Code Online (Sandbox Code Playgroud)
有要求:/ reservation?hotelName = myHotel
myHotel将绑定到ReservationCriteria对象中的hotelName。
但是,如何将参数绑定到嵌套对象DateRange?定义如下:
public class DateRange {
Date from;
Date to;
//getters-setters omitted
}
Run Code Online (Sandbox Code Playgroud)
有没有一种URL模式,它允许这种绑定,例如:
/reservation?hotelName=myHotel&reservationDateRange={fromDate=14.04.2016,toDate=15.04.2016}
Run Code Online (Sandbox Code Playgroud)
还是我必须声明单独的请求参数并手动绑定它们?
@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);
}
Run Code Online (Sandbox Code Playgroud)
我宁愿不修改ReservationCriteria类,因为它在许多其他项目中使用,这将导致进行大量重构。
Gam*_*tes 18
至少从 Spring 4 开始,您可以传入以“.”分隔的嵌套对象。在网址中。
在 OP 情况下,它将用于查询参数:
?reservationDateRange.from=2019-04-01&reservationDateRange.to=2019-04-03
Run Code Online (Sandbox Code Playgroud)
这假设可以从给定的字符串解析 Date。这可能不适用于任意级别的嵌套,但我已经测试过它可以与一个额外的嵌套对象一起使用。
当您将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);
}
Run Code Online (Sandbox Code Playgroud)
/ reservation?hotelName = value&from = val&to = val
这样,您可以受益于SpringMVC的标准转换器。
您尝试使用某种json来编排内部对象的尝试无效,因为默认情况下,Spring在查询字符串中无法理解此演示文稿,为此您提供了一个转换器。
更新本答案的答案:
如果要实现自定义Converter,则需要实现org.springframework.core.convert.converter.Converter<S, T>,然后在Spring Conversion Service上注册新的Converter。
在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>
Run Code Online (Sandbox Code Playgroud)
在Java配置上,您可以扩展WebMvcConfigurerAdapter并添加如下所示的bena:
@Configuration
@EnableWebMvc
public class YourWebConfigurationClass extends WebMvcConfigurerAdapter{
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(yourConverter());
}
...
}
Run Code Online (Sandbox Code Playgroud)
您的转换器可以如下所示:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在URL上生成列表: http://localhost:8080/reservation?hotelName=myHotel&reservationDateRange={"fromDate":"14.04.2016","toDate":"15.04.2016"}
请注意保留DateRange字段,因为我将其编码为json。
希望对您有所帮助
| 归档时间: |
|
| 查看次数: |
3534 次 |
| 最近记录: |