I have a room service which returns detail for rooms when requesting http://localhost:8082/room/search/byRoomChar
@GetMapping(path = "/search/byRoomChar") public @ResponseBody List<Room> byCapacity(@RequestParam(required = false) Integer capacity, @RequestParam(required = false) Boolean isUnderMaintenance, @RequestParam(required = false) String equipment) { return roomRepository.findByRoomChar(capacity, isUnderMaintenance, equipment); }
Now I want to request this @GetMapping from the booking service since this is the application gateway that users are going to interact with using the http://localhost:8081/booking/search/byRoomChar.
@GetMapping(path = "/search/byRoomChar") public @ResponseBody List<Room> byCapacity(@RequestParam(required = false) Integer capacity, @RequestParam(required = false) Boolean isUnderMaintenance, @RequestParam(required = false) String equipment) { ResponseEntity<Room[]> roomsResponse = restTemplate.getForEntity("http://localhost:8082/room/search/byRoomChar?capacity=" + capacity + "&isUnderMaintenance=" + isUnderMaintenance + "&equipment=" + equipment, Room[].class); return Arrays.asList(roomsResponse.getBody()); }
Room entity code:
package nl.tudelft.sem.template.entities; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "Room") public class Room { @EmbeddedId private RoomId id; @Column(name = "capacity") private int capacity; @Column(name = "numberOfPeople") private int numberOfPeople; @Column(name = "isUnderMaintenance", nullable = false) private boolean isUnderMaintenance; @Column(name = "equipment") private String equipment; public Room() { } public Room(long roomNumber, long buildingNumber, int capacity, int numberOfPeople, boolean isUnderMaintenance, String equipment) { RoomId id = new RoomId(roomNumber, buildingNumber); this.id = id; this.capacity = capacity; this.numberOfPeople = numberOfPeople; this.isUnderMaintenance = isUnderMaintenance; this.equipment = equipment; } public RoomId getId() { return id; } public void setId(RoomId id) { this.id = id; } public int getCapacity() { return capacity; } public void setCapacity(int capacity) { this.capacity = capacity; } public int getNumberOfPeople() { return numberOfPeople; } public void setNumberOfPeople(int numberOfPeople) { this.numberOfPeople = numberOfPeople; } public boolean getIsUnderMaintenance() { return isUnderMaintenance; } public void setUnderMaintenance(boolean underMaintenance) { isUnderMaintenance = underMaintenance; } public String getEquipment() { return equipment; } public void setEquipment(String equipment) { this.equipment = equipment; } }
Room repository code:
package nl.tudelft.sem.template.repositories; import java.util.List; import nl.tudelft.sem.template.entities.Room; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface RoomRepository extends JpaRepository<Room, Integer> { @Query("SELECT r FROM Room r WHERE (:number is null or r.id.number = :number)" + "and r.id.buildingNumber = :buildingNumber") List<Room> findByRoomNum(@Param("number") Long number, @Param("buildingNumber") Long buildingNumber); @Query("SELECT r FROM Room r WHERE (:capacity is null or r.capacity = :capacity) and" + "(:isUnderMaintenance is null or r.isUnderMaintenance = :isUnderMaintenance) and" + "(:equipment is null or r.equipment = :equipment)") List<Room> findByRoomChar(@Param("capacity") Integer capacity, @Param("isUnderMaintenance") Boolean isUnderMaintenance, @Param("equipment") String equipment); }
However, this does not work because when omitting parameters when calling the getmapping from the booking service all parameter values are turned into null because of the required=false. And this are converted into Strings inside the hard coded url.
2021-12-04 17:13:03.883 WARN 16920 --- [nio-8082-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [null]]
How can I make a get http request with optional parameters from within the code?
Advertisement
Answer
UriComponentsBuilder
can help with URI construction. It correctly handles nullable query parameters.
String uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8082/room/search/byRoomChar") .queryParam("capacity", capacity) .queryParam("isUnderMaintenance", isUnderMaintenance) .queryParam("equipment", equipment) .encode().toUriString(); ResponseEntity<Room[]> roomsResponse = restTemplate.getForEntity(uri, Room[].class);
Also, following answer can be helpful: https://stackoverflow.com/a/25434451/5990117