简体   繁体   中英

Spring - how to map request parameters in the URL to a POJO at run time?

I need to know how Spring boot maps the request parameters in the URL to a POJO at run time.

Here is an example URL with parameters

    http://localhost:8080/api/public/properties?serviceType.in=SALE&title.contains=some text&price.greaterOrEqualThan=500&price.lessOrEqualThan=50000&propertyType.in=HOUSE&locationId.in=1,2&landSize.greaterOrEqualThan=100&landSize.lessOrEqualThan=1000&bedrooms.greaterOrEqualThan=2&bedrooms.lessOrEqualThan=5&bathrooms.greaterOrEqualThan=1&bathrooms.lessOrEqualThan=3&ageType.in=BRAND_NEW

I have a number of Criteria classes that all extends PropertyCriteria class. To give an example, if the request contains no parameters, I want the controller to use the PropertyCriteria. If the request contains a bedrooms parameter, I want the controller to use the HousePropertyCriteria and so on. See controller method example below.

@GetMapping("/public/properties")
public ResponseEntity<List<Property>> 
   getAllPropertiesNested(HttpServletRequest request) {

   if (condition1 == true) {
       EntityOnePropertyCriteria c1 = new EntityOnePropertyCriteria();
       //populate c1 using request object

   } else {
       EntityTwoPropertyCriteria c2 = new EntityTwoPropertyCriteria();
       //populate c2 using request object
   }

}

Two ways of doing this manually: 1) I wonder if in your project you have access to HttpServletRequest object. If that is the case, you can use the method request.getParameter(nameParam) to populate the object that you need.

2) Use beanutils library and using the method BeanUtils.copyProperties(dest, source) Using "@RequestParam Map source" in your controller and replacing the dest object you want fill

I found the answer on this link .

public static void applyMapOntoInstance(Object instance, Map properties) {

    if (properties != null && !properties.isEmpty()) {
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(instance);
        beanWrapper.setAutoGrowNestedPaths(true);

        for (Iterator<?> iterator = properties.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry<String, ?> entry = (Map.Entry<String, ?>) iterator.next();
            String propertyName = entry.getKey();
            if (beanWrapper.isWritableProperty(propertyName)) {
                beanWrapper.setPropertyValue(propertyName, entry.getValue());
            }
        }
    }
}

My controller method now looks like:

@GetMapping("/public/properties")
@Timed
public ResponseEntity<List<Property>> getAllPropertiesNested(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {


    HttpHeaders headers = null;
    if (requestContains("bedrooms", request)) {

        HousePropertyCriteria housePropertyCriteria = new HousePropertyCriteria();
        applyMapOntoInstance(housePropertyCriteria, request.getParameterMap());

        Page<HouseProperty> page = housePropertyQueryService.findByCriteriaNested(housePropertyCriteria, pageable);
        headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/public/properties");
        return new ResponseEntity(page.getContent(), headers, HttpStatus.OK);

    } else {
        Page<Property> page = propertyQueryService.findByCriteriaNested(criteria, pageable);
        headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/public/properties");
        return new ResponseEntity(page.getContent(), headers, HttpStatus.OK);
    }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM