Backend/JAVA

JAVA에서 html 다루기 (Jsoup)

dddzr 2023. 8. 16. 14:08

JAVA에서 html을 String 데이터로 들고 있는데 특정 요소에 속성을 추가하는게 필요했습니다.

 

라이브러리 종류

3가지 방법(Jsoup, javax.swing.text.html3, HTML Template Engine)에 대해 알아보았는데

아래에 각 라이브러리의 사용 사례와 특징을 설명하겠습니다. 선택 시 프로젝트의 요구사항과 개발 환경을 고려하여 결정하시면 됩니다.

1. Jsoup: HTML을 파싱하고 조작하는 작업에 우수한 성능을 제공하는 라이브러리입니다. 주로 웹 스크래핑, HTML 파싱, 수정, 정보 추출 등에 사용됩니다. 특히 복잡한 HTML 문서를 다루는 데 편리하며, 간단한 DOM 조작과 선택이 필요한 경우에도 유용합니다.

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

public class HtmlManipulation {
    public static void main(String[] args) {
        String html = "<div id=\"myDiv\">Hello, World!</div>";
        
        Document document = Jsoup.parse(html);
        Element divElement = document.getElementById("myDiv");
        
        // 추가할 속성 설정
        divElement.attr("newAttribute", "newAttributeValue");
        
        System.out.println(divElement);
    }
}



2. HTML DOM Parsing (javax.swing.text.html): Java에서 제공하는 기본 라이브러리로, HTML 문서를 파싱하고 DOM을 구성하여 조작할 수 있습니다. 자바 기본 라이브러리를 사용하여 간단한 HTML 파싱과 조작이 필요한 경우에 적합합니다.

import javax.swing.text.html.parser.ParserDelegator;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import java.io.StringReader;

public class HtmlManipulation {
    public static void main(String[] args) throws Exception {
        String html = "<div id=\"myDiv\">Hello, World!</div>";

        ParserDelegator parser = new ParserDelegator();
        MutableAttributeSet attributes = new MutableAttributeSet();

        parser.parse(new StringReader(html), new HTMLEditorKit.ParserCallback() {
            public void handleStartTag(HTML.Tag tag, MutableAttributeSet attrSet, int pos) {
                if (tag == HTML.Tag.DIV) {
                    // 추가할 속성 설정
                    attrSet.addAttribute("newAttribute", "newAttributeValue");
                }
            }
        }, true);

        System.out.println(attributes);
    }
}



3. HTML Template Engine (FreeMarker, Thymeleaf): 템플릿 엔진을 사용하여 동적 HTML 생성 및 조작을 지원합니다. 주로 웹 애플리케이션의 뷰 레이어에서 사용되며, 서버 측에서 HTML을 생성하고 클라이언트로 보내는 데 적합합니다. 데이터와 템플릿을 결합하여 동적인 웹 페이지를 생성할 수 있습니다.

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class HtmlManipulation {
    public static void main(String[] args) throws IOException, TemplateException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
        cfg.setClassForTemplateLoading(HtmlManipulation.class, "/");
        
        Map<String, Object> templateData = new HashMap<>();
        templateData.put("newAttribute", "newAttributeValue");
        
        Template template = cfg.getTemplate("template.html");
        StringWriter writer = new StringWriter();
        template.process(templateData, writer);
        
        String manipulatedHtml = writer.toString();
        System.out.println(manipulatedHtml);
    }
}

 

Jsoup 예시

Jsoup를 사용한 코드이다.

마지막 replace부분은 vue3에서 컴포넌트를 추가하는데

속성을 사용하여 HTML을 동적으로 추가할 때, HTML 표준에 따른 동작으로 HTML 태그 이름은 기본적으로 소문자로 처리되기 때문에 이를 처리하는 코드입니다.

import java.util.Map.Entry;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.io.IOException;
import org.codehaus.jackson.type.TypeReference;
  
  private String addAttr(String html, String componentData) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    HashMap<String, Object> components = mapper.readValue(componentData, new TypeReference<HashMap<String, Object>>() {
    });
    for (Entry<String, Object> comp : components.entrySet()) {
      String key = comp.getKey().trim();
      HashMap component = (HashMap) comp.getValue();
      if(component.get("condition").equals("addAttr")){
        Document document = Jsoup.parse(html);
        Elements element = document.select("#"+key);
        element.attr("tempData", (String) component.get("tempData"));
        html = document.toString();
      }
    }
    html = html.replaceAll("<componentname ", "<ComponentName ").replaceAll("</componentname>", "</ComponentName>");
    return html;
  }