model에 담은 값 화면에 뿌리기
@GetMapping({ "/" })
public String main(Model model) {
// 서비스가 필요없어서(CRUD의 R만 하면됨) 레파지토리 바로 호출
List<Post> postsEntity = postRepository.mFindByPopular();
model.addAttribute("posts", postsEntity);
return "main";
}
모델에 담은 데이터를 머스태치에 뿌리는데
content 내용을 뿌릴때는 html을 인식하기 위해 중괄호 3개를 써줘야 한다.
content에 담을 때 p태그까지 담기게 담아줬기 때문이다.
게시글 내용에는 글 뿐만 아니라 사진과 같은 다른 타입들이 들어가 있는데
메인에 모든 게시글 목록을 뿌릴 때는 글만 뿌려야 한다.
content 내부에 이미지까지 보이기 때문에 content 내용을 파싱하여 img 태그를 없애줘야 한다.
제이수프(Jsoup) 다운로드
html 데이터를 가져와서 파싱 하는 라이브러리 중에 제이 수프를 사용해볼 것이다.
jsoup : HTML 문서에 저장된 데이터를 구문 분석, 추출 및 조작하도록 설계된 오픈 소스 Java 라이브러리이다.
제이수프 라이브러리 추가
변수 doc에는 html 파일을 모두 받는다.
css 선택자로 element를 찾는 select 함수는 여러 개가 있을 수 있기 때문에 항상 배열을 리턴해서 Elements 타입이다.
selectFirst라는 함수도 있는데, 얘는 하나만 리턴해주기 때문에 Element 타입이다.
라이브러리를 추가해주자.
// jsoup HTML parser library @ https://jsoup.org/
implementation 'org.jsoup:jsoup:1.14.3'
gradle 작업할 때는 서버를 꺼줘야 한다.
build.gradle에 의존성 주입해주자.
그리고 유틸에 html을 파싱 하는 파일을 만들어준다.
package site.metacoding.blogv3.util;
public class UtilPost {
// 책임 : img 태그 제거
public static String getContentWithoutImg(String content) {
return "";
}
}
Jsoup 테스트
시작하기 전에 Junit으로 테스트부터 해줄 것이다.
package site.metacoding.blogv3;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.jupiter.api.Test;
public class UtilPostTest {
@Test
public void getContentWithoutImg_테스트() {
// 1. 가짜데이터
String html = "안녕 <img src='#'> 반가워";
Document doc = Jsoup.parse(html);
System.out.println(doc);
// 2. 실행
// 3. 검증
}
}
@Test
public void getContentWithoutImg_테스트() {
// 1. 가짜데이터
String html = "안녕 <img src='#'> 반가워";
Document doc = Jsoup.parse(html);
// System.out.println(doc);
// 2. 실행
Elements els = doc.select("img");
System.out.println(els.size());
// 3. 검증
}
size를 확인해보니 1로 img태그를 잘 찾는다.
이제 for문 돌면서 img 태그를 찾아서 삭제하면 된다.
@Test
public void getContentWithoutImg_테스트() {
// 1. 가짜데이터
String html = "안녕 <img src='#'> 반가워";
Document doc = Jsoup.parse(html);
// System.out.println(doc);
// 2. 실행
Elements els = doc.select("img");
for (Element el : els) {
el.remove();
}
System.out.println(doc);
// 3. 검증
}
잘 삭제되니까 다시 이미지 태그를 찾아서 size가 0이면
문자열로 바꿔서 리턴해주면 끝이다.
public class UtilPostTest {
@Test
public void getContentWithoutImg_테스트() {
// 1. 가짜데이터
String html = "안녕 <img src='#'> 반가워";
Document doc = Jsoup.parse(html);
// System.out.println(doc);
// 2. 실행
Elements els = doc.select("img");
for (Element el : els) {
el.remove();
}
// System.out.println(doc);
// 3. 검증
Elements elsVerify = doc.select("img");
assertTrue(elsVerify.size() != 0);
System.out.println(doc.select("body").html());
}
}
테스트가 정상적으로 끝났으니 실제 파일에 코드를 작성해보자.
content 내용을 받아와서 파싱 해준다.
package site.metacoding.blogv3.util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class UtilPost {
// 책임 : img 태그 제거
public static String getContentWithoutImg(String content) {
Document doc = Jsoup.parse(content);
Elements els = doc.select("img");
for (Element el : els) {
el.remove();
}
// 3. 검증
Elements elsVerify = doc.select("img");
return doc.select("body").html(); // body안에 데이터를 스트링으로 변환
}
}
이미지 태그는 잘 제거되었는데 만약 진하게 글을 쓰면 태그까지 다 들어간다.
모든 태그를 다 날려버리기 위해 .html( )을 .text( )로 바꿔서 리턴해주면 된다.
이제 게시글 카드를 클릭하면 글 상세보기 화면으로 넘어가게 a태그를 걸어주자.
포스트 부분을 클릭하면 상세보기로 넘어가고, 유저 아이디를 클릭하면 유저의 블로그로 넘어가자.
[출처]
https://cafe.naver.com/metacoding
https://www.youtube.com/c/%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9