Optional Path Variables in Spring Web MVC

With a Spring Web MVC controller endpoint in Java you cannot have an optional @PathVariable, so you have to do things old school. In my code I wanted a default sorting mechanism, if the caller of my endpoint didn’t put in any sort parameters. The sort (orderBy) parameters are the fields, and the direction of the sort is specified in an already provided Spring enumeration that I pass a string value to.

The whole *secret* — just pass the HttpServletRequest object into the controller method.  That’s it.

Note my setup is Spring core libraries (and MVC) 3.2.4, Spring Data JPA 1.4.1, and Hibernate for the dialect version 4.2.1 with JPA Api 1.0.1.

Endpoint in the Controller:

@ApiOperation(value=“look for list by sorting”,

     notes= ” two optional parameters: orderBy = {fieldA, fieldB, fieldC} “

          + “direction = {ASC,DESC}”)

@RequestMapping(method = RequestMethod.GET, value = “/look”)

public
@ResponseBody

List<ObjectDto> findSorted(HttpServletRequest request) {

    return dataService.findSorted (request.getParameter(“orderBy”), request.getParameter(“direction”));

}

This calls the service, which builds a Pageable object. I haven’t had a need to refactor the method so I just left the code in the service method for now. There are a few ternaries to check for nulls (note: PMD has a base rule to not reuse method parms as well).

Method in the Service:

private
final
static String DEFAULT_ORDER = “fieldA”;

private
final
static String DEFAULT_DIRECTION =
ASC;

public List<Object> getEntities(Pageable pageable) {

    return objectRepository.findAll(pageable).getContent();

}

public List<ObjectDto> getDTOs(Pageable pageable) {

    return objectMapper.toDTOs(getEntities(pageable), ObjectDto.class);

}

public List< ObjectDto > findSorted (String orderBy, String direction) {

String order = orderBy == null ? DEFAULT_ORDER : orderBy;

String dir = direction == null ? DEFAULT_DIRECTION : direction;


final PageRequest pageable = new PageRequest(

     0, Paging.PAGING_SIZE, new Sort(

     new Order(Direction.fromString(dir), order)));

return objectService.getDTOs (pageable);

}

The mapper code is simple, using commons BeanUtils:

    BeanUtils.copyProperties(fromEntity, toDto);

And the repository code extends JPARepository, so there is already a findAll(pageable) function in the canned interface.

Comments are closed.