적용 방법은 아래와 같다.
① 마크다운 문서 작성
② Spring 환경에서 HTML 문서로 동적 변환하여 화면 출력
마크다운 문서를 HTML 로 변환하는 것은 여러 가지 방법을 고려하였으나 filter 를 사용하는 것을 선택했다. 마크다운 파싱과 HTML랜더링은 이슈관리 툴 Jira 로 널리 알려진 Atlassian 의 오픈소스 https://github.com/atlassian/commonmark-java 를 사용하였다.
1. 라이브러리 추가
Maven빌드 툴을 사용하고 있기 때문에 아래와 같이 라이브러리를 pom.xml 파일에 추가한다.
org.springframework.restdocs spring-restdocs-mockmvc 2.0.0.RELEASE
2. 필터 만들기
필터는 "org.springframework.web.filter.OncePerRequestFilter" 클래스를 상속받아 구현하였으며 어노테이션을 통하여 배포되도록 구성하였다. import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FileUtils; import org.apache.tika.io.IOUtils; import org.commonmark.node.Node; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.web.context.support.ServletContextResourceLoader; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.UrlPathHelper; import architecture.community.web.util.ServletUtils; @WebFilter(filterName = "makedownFilter", urlPatterns = "*.md") public class MakedownViewFilter extends OncePerRequestFilter { private Logger log = LoggerFactory.getLogger(getClass()); private UrlPathHelper urlPathHelper = new UrlPathHelper(); private ResourceLoader resourceLoader ; @Override protected void initFilterBean() throws ServletException { super.initFilterBean(); resourceLoader = new ServletContextResourceLoader(this.getServletContext()); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String url = urlPathHelper.getLookupPathForRequest(request); Resource resouce = getResourceForUrl(url); log.debug("URL : {} - {}", url, resouce.exists() ); // 리소스가 존재하는 경우만 처리하며 이외의 경우는 다음 필터가 적용 되도록 한다. if( resouce.exists() ) { Parser parser = Parser.builder().build(); Node document = parser.parse( FileUtils.readFileToString(resouce.getFile(), ServletUtils.DEFAULT_HTML_ENCODING) ); HtmlRenderer renderer = HtmlRenderer.builder().build(); ServletUtils.setContentType(ServletUtils.DEFAULT_HTML_CONTENT_TYPE, response); IOUtils.write( renderer.render(document), response.getWriter() ); response.flushBuffer(); return; } super.doFilter(request, response, filterChain); } /** * url 에 해당한는 리소스를 리턴한다. * @param url * @return */ protected Resource getResourceForUrl(String url) { return resourceLoader.getResource(url); } }
댓글 없음:
댓글 쓰기