empty, null 체크, 빈 리스트 체크
has_content와 ?? 를 사용해 빈 리스트인, null인지 아닌지 체크할 수 있다.
이전에는 if_exists로 검사했었지만 더는 권장되지 않는다.
<#if [Object]?has_content>
...
</#if>
has_content는 리스트(오브젝트)가 존재하는지(size가 1 이상인지) 검사함과 함께 동시에 null 검사도 수행한다.
검사하는 리스트가 빈 값이거나 존재하지 않으면 false를 반환하고, 값이 존재하는 경우 true를 반환한다.
리스트에 빈 객체가 들어와 있는 경우가 생길 수 있는데, 이러한 경우 has_content가 제대로 동작하지 않는다.
예시로, 컨트롤러에서 list 타입이 아닌 객체 값을 넣어주었다고 가정한다.
@Controller
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping("/")
public void home(Model model) {
ProductVO data = productService.select();
model.addAttribute("data", data);
return "home";
}
}
productService.select()에서 가져오는 값은 빈 값이라고 가정한다.
ProductVO 타입 객체인 data에 빈 값이 저장되어 있는 것이다.
따라서 프리마커 home.ftl에 전달되는 data도 빈 값이 저장된 상태로 전달된다.
ProductVO는 다음과 같이 필드가 선언되어 있다.
@Getter
@Setter
public class ProductVO {
private String id;
private String desc;
}
home.ftl 파일에서 data가 어떤 방식으로 검사 될 수 있는지 살펴본다.
<#assign data = ${data}>
<#if data?has_content>
...
</#if>
현재 변수 data에는 "" 값이 들어있는 상태이다. 빈 객체만 존재한다.
이 상태에서 data의 size를 (data?size) 구하면 1이 나온다. 그리고 has_content는 데이터가 있는 것으로 인식하여 true 값을 반환하므로 해당 if문은 실행된다.
하지만 아래처럼 작성하면 p 태그 내에 아무런 내용도 뜨지 않는다.
<#assign data = ${data}>
<#if data?has_content>
<p>${data.id}</p>
</#if>
따라서 객체 값을 전달해줄 때에는 조건절을 잘 설정해야 하거나, 상황에 따라 데이터를 받아올 때 추가적인 전처리가 필요할 수 있다.
프리마커 ??
처음에?? 를 보고 이건 뭐지 했는데
?? 은 null을 체크한다.
<#if [Object]??>
...
</#if>
이도 has_content와 마찬가지로 list 타입 데이터가 null인지 아닌지 체크하는 것이다.
list 타입이 아닌 객체 값을 검사하는 것이라면 has_content와 ?? 말고 exists를 사용하면 된다.