코드 조각 관리 게시판
Spring MVC 프로젝트에 Spring MyBatis 를 이용한다.
코드 조각 관리 게시판은 해당 언어에 맞춰 코드 하이라이트가 되는 게시판이다.
버튼을 누를 때마다 해당 언어만 필터링 되어 출력된다.
파일 구성🔎
패키지(경로) | 파일명 |
com.test.controller | |
CodeController.java | |
com.test.persistence | |
CodeDAO.java (interface) | |
CodeDAOImpl.java | |
com.tet.domain | |
CodeDTO.java | |
views | |
list.jsp | |
view.jsp | |
add.jsp | |
src/main/resources/mapper | |
code.xml | |
root | |
script.spl |
초기 세팅🔎
컴포넌트 등록 - servlet-context.xml
<context:component-scan base-package="com.test.controller" />
<context:component-scan base-package="com.test.persistence" />
나머지는 아래 글 참조
https://steady-record.tistory.com/entry/Spring-스프링-프로젝트-설정-일괄-적용
구현 코드🔎
script.sql
create table tblCode (
seq number primary key,
subject varchar2(1000) not null,
code varchar2(2000) not null,
regdate date default sysdate not null,
language varchar2(100) not null
);
create sequence seqCode;
- 초기 세팅
CodeController.java
package com.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.test.persistence.CodeDAO;
@Controller
public class CodeController {
@Autowired
private CodeDAO dao;
}
CodeDTO.java
package com.test.domain;
import lombok.Data;
@Data
public class CodeDTO {
private String seq;
private String subject;
private String code;
private String regdate;
private String language;
}
CodeDAO.java
package com.test.persistence;
public interface CodeDAO {
}
CodeDAOImpl.java
package com.test.persistence;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class CodeDAOImpl implements CodeDAO{
@Autowired
private SqlSessionTemplate template;
}
CodeDAOImpl는 SqlSessionTemplate에 의존한다. 그래서 의존관계를 형성하기위해 xml 파일에 등록하거나 @Bean 를 사용해야한다. 하지만 @Autowired를 사용하면 각 상황의 타입에 맞는 IoC컨테이너 안에 존재하는 Bean을 자동으로 주입한다.
또한, 의존성 주입 타켓이 되는 Class 역시 당연히 Bean으로 등록이 되기위한 @Repository이 부여하는 것을 잊지 말아야 한다.
- 글 등록하기
CodeController.java
@GetMapping(value="/add.do")
public String add() {
return "add";
}
@PostMapping(value="/addok.do")
public String addok(CodeDTO dto) {
int result = dao.add(dto);
if (result == 1) {
return "redirect:/list.do";
} else {
return "redirect:/add.do";
}
}
CodeDAOImpl.java
@Override
public int add(CodeDTO dto) {
return this.template.insert("code.add", dto);
}
code.xml
<insert id="add" parameterType="com.test.domain.CodeDTO">
insert into tblCode (seq, subject, code, regdate, language) values (seqCode.nextval, #{subject}, #{code}, default, #{language})
</insert>
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Code</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
</head>
<body>
<!-- add.jsp -->
<h1>Code <small>add</small></h1>
<form method="POST" action = "/code/addok.do">
<table class="vertical">
<tr>
<th>제목</th>
<td><input type="text" name="subject" required class="full" ></td>
</tr>
<tr>
<th>코드</th>
<td><textarea name="code" required class="full"></textarea></td>
</tr>
<tr>
<th>언어</th>
<td>
<select name="language">
<option value="java">Java</option>
<option value="sql">SQL</option>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
</select>
</td>
</tr>
</table>
<div>
<button type="submit" class="add">추가</button>
<button type="button" class="back" onclick="loaction.href='/code/list.do';">돌아가기</button>
</div>
</form>
<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
</body>
</html>
- 목록보기
CodeController.java
@GetMapping(value="/list.do")
public String list(Model model, @RequestParam(name="language", required = false) List<String> language) {
List<CodeDTO> list = dao.list(language);
model.addAttribute("list", list);
model.addAttribute("language", language);
return "list";
}
목록보기에는 검색 기능이 있기에 주소가 넘어오는 경우의 수를 여러개 생각할 수 있다. 이럴 때는 파라미터가 여러개 넘어오는 기준으로 작성한다.
<수신되는 주소 경우의 수>
1. list.do
2. list.do?language=java
3. list.do?language=java&language=css
검색을 하지 않았을 경우 language 변수는 넘어가지않는데, required = true 가 기본 값이기에 에러가 난다. 그래서 false로 설정해준다.
CodeDAOImpl.java
@Override
public List<CodeDTO> list(List<String> language) {
return this.template.selectList("code.list", language);
}
code.xml
<select id="list" parameterType="java.util.List" resultType="com.test.domain.CodeDTO">
select seq, subject, regdate, language from tblCode
<if test="list != null">
<where>
<foreach collection="list" item="lang" separator="or">
language = #{lang}
</foreach>
</where>
</if>
order by seq desc
</select>
매개변수 language 하나만 넘어왔으므로 편의성을 위해 list로 칭한다.
foreach의 separator는 루프를 한번 돌면 뒤에 자동으로 붙여주는 역할을 한다.
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Code</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<style>
#main {
display: grid;
grid-template-columns: repeat(3, 1fr)
}
.item {
border: 1px solid #aaa;
width: 240px;
margin: 5px;
cursor: pointer;
}
.item > div:nth-child(1) {
padding: .5rem;
}
.item > div:nth-child(2) {
min-height: 150px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.item > div:nth-child(3) {
padding: .5rem;
text-align: right;
}
#filter {
text-align: right;
padding-right: 2rem;
}
#filter input{
background-color: #fff;
}
</style>
</head>
<body>
<!-- list.jsp -->
<h1>Code <small>list</small></h1>
<div id="filter">
<input type="button" value="Java" data-language="java" data-selected="0" data-color="tomato">
<input type="button" value="SQL" data-language="sql" data-selected="0" data-color="gold">
<input type="button" value="HTML" data-language="html" data-selected="0" data-color="orange">
<input type="button" value="CSS" data-language="css" data-selected="0" data-color="cornflowerblue">
<input type="button" value="JavaScript" data-language="js" data-selected="0" data-color="yellowgreen">
</div>
<div id="main">
<c:forEach items="${list}" var="dto">
<div class="item" onclick="location.href='/code/view.do?seq=${dto.seq}';">
<c:choose>
<c:when test="${dto.language == 'java' }">
<c:set var="color" value="tomato" />
</c:when>
<c:when test="${dto.language == 'sql' }">
<c:set var="color" value="gold" />
</c:when>
<c:when test="${dto.language == 'css' }">
<c:set var="color" value="cornflowerblue" />
</c:when>
<c:when test="${dto.language == 'html' }">
<c:set var="color" value="orange" />
</c:when>
<c:when test="${dto.language == 'js' }">
<c:set var="color" value="yellowgreen" />
</c:when>
<c:otherwise>
<c:set var="color" value="white" />
</c:otherwise>
</c:choose>
<div style="background-color: ${color};">${dto.language}</div>
<div>${dto.subject}</div>
<div>${dto.regdate}</div>
</div>
</c:forEach>
</div>
<div>
<button type="button" class="add" onclick="location.href='/code/add.do';">추가하기</button>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
<script>
$('#filter > input').click(function() {
let param='';
if ($(this).data('selected') == 0) {
$(this).css('background-color', $(this).data('color'));
$(this).data('selected', '1');
} else {
$(this).css('background-color', '#fff');
$(this).data('selected', '0');
}
$('#filter > input').each(function(index, item) {
if ($(item).data('selected') == '1' ) {
//alert($(item).data('language'));
param += 'language=' + $(item).data('language') + '&';
}
});
//alert(param);
location.href = '/code/list.do?'+ param;
});
<c:forEach items="${language}" var="lang">
$('#filter input[data-language=${lang}]').data('selected', '1');
$('#filter input[data-language=${lang}]').css('background-color', $('#filter input[data-language=${lang}]').data('color'));
</c:forEach>
</script>
</body>
</html>
1. 검색 버튼에도 언어마다 색깔을 다르게 출력한다.
2. 글 제목에는 언어마다 색깔을 다르게 출력한다.
3. 버튼을 누르면 누적으로 검색결과가 출력되고 이미 누른 버튼을 다시 누르면 취소가 된다.
- 글 상세보기
CodeController.java
@GetMapping(value="/view.do")
public String view(Model model, String seq) {
CodeDTO dto = dao.get(seq);
model.addAttribute("dto", dto);
return "view";
}
CodeDAOImpl.java
@Override
public CodeDTO get(String seq) {
return this.template.selectOne("code.get", seq);
}
code.xml
<select id="get" parameterType="String" resultType="com.test.domain.CodeDTO">
select * from tblCode where seq = #{seq}
</select>
view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Code</title>
<link rel="stylesheet" href="https://me2.do/5BvBFJ57">
<link rel="stylesheet" href="/code/resources/highlight/styles/github.min.css">
<style>
table tr:nth-child(1) th {
width: 120px;
}
table tr:nth-child(1) td {
width: 263px;
}
#code {
margin: 1rem;
border: 1px solid #ccc;
}
#code * {
font-family: consolas;
}
</style>
</head>
<body>
<!-- view.jsp -->
<h1>Code <small>view</small></h1>
<table>
<tr>
<th>번호</th>
<td>${dto.seq}</td>
<th>날짜</th>
<td>${dto.regdate }</td>
</tr>
<tr>
<td colspan="4">${dto.subject}</td>
</tr>
</table>
<pre id="code"><code class="language-${dto.language}"><c:out value="${dto.code}"/></code></pre>
<div>
<button type="button" class="back" onclick = "location.href='/code/list.do';">돌아가기</button>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" ></script>
<script src="/code/resources/highlight/highlight.min.js"></script>
<script>
hljs.highlightAll();
</script>
</body>
</html>
코드 하이라이트 사용하는 방법은 해당 글 하단을 참고한다.
코드 하이라이트🔎
코드 하이라이트는 코드의 문법을 강조하기 위한 스타일이다.
아래와 같이 사이트를 이용하여 js 를 다운받으면 편리하게 적용할 수 있다.
code highlight 사이트는 많아 아무 사이트를 이용하여도 괜찮다.
1. 사이트 접속
2. 사용할 언어 체크 및 다운로드
3. 압축 해제 및 폴더 붙여넣기
다운로드 받은 파일을 압축 해제 후 폴더를 통채로 webapp > resources 밑에 붙여 넣는다.
4. 사용할 jsp 에 코드 추가
<script src="/code/resources/highlight/highlight.min.js"></script>
<script>
hljs.highlightAll();
</script>
5. header 태그에 추가 및 스타일 적용
<link rel="stylesheet" href="/code/resources/highlight/styles/github.min.css">
href 에는 아까 다운받았던 highlight 폴더의 style 폴더 내에서 선택하여 적용한다.
dark, github 스타일도 있다.
7. <pre>, <code>, <c:out> 태그로 코드내용 감싸기
<pre><code class="language-java"><c:out value="코드내용"/></code></pre>
pre, code 태그로 감싸고 class는 language-언어명 을 사용한다.
또한 c:out 태그를 사용하면 사이트에서 코드를 해석하지 않고 문자열 그대로 출력한다.
'Spring' 카테고리의 다른 글
[Spring] Apache Commons IO 라이브러리(1) : file 입출력 (0) | 2023.11.29 |
---|---|
[Spring] Tiles 프레임워크 : 레이아웃 프레임워크 (0) | 2023.11.29 |
[Spring] MyBatis 쿼리문 작성하기 (0) | 2023.11.27 |
[Spring] MyBatis 와 Spring 연동하기(2) : DBCP 사용하기 (0) | 2023.11.27 |
[Spring] MyBatis 와 Spring 연동하기(1) : XML Mapper를 사용한 연동 (0) | 2023.11.27 |