Spring REST-将GET参数绑定到嵌套对象 [英] Spring REST - binding GET parameters to nested objects

查看:107
本文介绍了Spring REST-将GET参数绑定到嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道您可以将get请求参数绑定到如下的pojo:

I know you can bind get request parameters to a pojo like:

@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
}

有要求:/reservation?hotelName = myHotel

With a request: /reservation?hotelName=myHotel

myHotel将绑定到ReservationCriteria对象中的hotelName.

myHotel will be bound to hotelName in ReservationCriteria object.

但是如何将参数绑定到嵌套对象DateRange?定义如下:

But how can I bind parameters to the nested object DateRange? Which defined like:

public class DateRange {
    Date from;
    Date to;

    //getters-setters omitted
}

有没有一种URL模式,可以进行如下绑定:

Is there a URL pattern which allows that kind of binding something like:

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

还是我必须声明单独的请求参数并手动绑定它们?

Or do I have to declare seperate request parameters and bind them manually?

@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类,因为它在许多其他项目中使用,这将导致大量重构.

I would prefer not to modify ReservationCriteria class because it is used in many other projects, which would cause alot of refactoring to be made.

推荐答案

当您将POJO作为数据容器传递时,Spring使用属性名称来构建查询字符串,并与所传递的数据一起来构建pojo.一个合适的转换器.这适用于平面pojo或换句话说没有嵌套,为此,您提供了转换器.由于这个原因,您感冒的想法如下:

When you pass a POJO as container of data, Spring use the name of the properties for build the query string and with the data that you pass build the pojo through an appropriated converter. This works for planar pojo or in other words without nesting, for this purpose you have provide the your converter. for this reason you cold have a think like below:

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);
}

/reservation?hotelName = value& from = val& to = val

/reservation?hotelName=value&from=val&to=val

通过这种方式,您可以受益于SpringMVC的标准转换器.

in this way you can benefit of standard converter of SpringMVC.

您尝试使用某种json来编排内部对象的尝试无效,因为默认情况下,Spring在查询字符串中无法理解此演示文稿,为此您提供了一个转换器.

the your attempt to use a sort of json for codificate the inner object didn't work because Spring by default in query string don't understand this presentation you have provide a converter for this purpose.

更新有关本评论的答案:

如果要实现自定义转换器,则必须实现org.springframework.core.convert.converter.Converter<S, T>,然后在Spring Conversion Service上注册新的Converter.

If you want implement a custom Converter you had implements the org.springframework.core.convert.converter.Converter<S, T> and then register the your new Converter on the Spring Conversion Service.

在xml配置上,您可以使用FormattingConversionServiceFactoryBean并将其注册在mvc命名空间中,如下所示:

On xml configuration you can use FormattingConversionServiceFactoryBean and register it on mvc namespace like below:

<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并添加如下所示的bena:

on java config you can extends WebMvcConfigurerAdapter and add you bena like below:

@Configuration
@EnableWebMvc
public class YourWebConfigurationClass extends WebMvcConfigurerAdapter{

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

   ...

}

您的转换器可以如下所示:

the your converter can be like below:

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"}

in this way you can listgening on the url: http://localhost:8080/reservation?hotelName=myHotel&reservationDateRange={"fromDate":"14.04.2016","toDate":"15.04.2016"}

请注意保留DateRange字段,因为我将其编码为json.

pleas pay attenction on reservation DateRange field because I encoded it like a json.

我希望它能为您提供帮助

I hope that it can help you

这篇关于Spring REST-将GET参数绑定到嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆