게시판 만들기-회원탈퇴 및 게시판 삭제 플래그 추가
2019-04-25 00:00:00 +0000회원 탈퇴
- 회원 탈퇴 기능을 만들면 탈퇴한 회원여부를 flag로 기록해야한다
- 데이터 보존을 위한 용도
- 회원탈퇴 추가
- 로그인 : 탈퇴한 회원 로그인 안되게.. 로그인 시 탈퇴한 회원이 아닌 회원의 비밀번호 체크 ( 0 )
- 게시물 : 탈퇴한 회원 게시물 플래그 수정
- 검색 : 탈퇴한 회원 id로 검색안되도록 수정
- 회원가입 : 회원가입 시 탈퇴한 회원 id 체크 제외 ( 0)
회원 정보 아이콘 추가
- bootstrap awesome font ‘fa-user’ icon을 추가한다
<c:when test="${not empty userVO.id}">
${userVO.name} 님 환영합니다
<span id="user-logout-button">로그아웃</span>
<span id="user-info-form"><i class="fas fa-user fa-2x"></i></span>
</c:when>
회원 탈퇴 URL 정의
- 회원정보 userInfoForm.jsp를 페이지를 추가한다
- 회원정보 아이콘을 누른 뒤 회원이 존재한다면 페이지 이동을 하고 존재하지 않는다면 알람을 띄운다
url | 설명 | Method |
---|---|---|
/user/info | 유저가 존재하는지 체크 | POST |
/user/info | 유저 정보 페이지로 이동 | GET |
/user/leave | 회원 탈퇴 | GET |
DB 수정
- 유저 삭제 flag 추가
alter table user add USER_DEL boolean DEFAULT '0';
- VO 수정
- userVO에 userDel 멤버변수를 추가한다
private boolean userDel; // userVO에 추가
- 유저 정보를 가져올 때 유저가 삭제되었는지 여부도 조건으로 건다
- 유저 탈퇴 플래그를 수정하는 쿼리를 만든다
<select id="getUserVO" parameterType="String" resultType="UserVO">
SELECT user_seq as userSeq
, id
, password
, name
, user_del as userDel
FROM user
WHERE id = #{id}
AND user_del != 1
</select>
<update id="updateUserDelFlag" parameterType="Long">
UPDATE user
SET user_del = 1
WHERE user_seq = #{userSeq}
</update>
회원 탈퇴 처리
- 회원 탈퇴 시 플래그를 수정하고 session 에서 삭제
@Override
public ResultMap updateUserDelFlag(final Long userSeq, HttpSession session) throws Exception {
int result = dao.updateUserDelFlag(userSeq);
if(0 == result) {
throw new LogicException("609", "알 수 없는 에러로 회원탈퇴에 실패했습니다");
}
session.invalidate();
ResultMap resultMap = new ResultMap();
resultMap.setStatus("200");
resultMap.setMsg("");
return resultMap;
}
게시판 삭제 flag 추가
- board 테이블에 삭제 플래그 추가
alter table board add BOARD_DEL boolean DEFAULT '0';
- boardVO 에 삭제 플래그 추가
private boolean boardDel; // boardVO에 추가
- 삭제버튼 클릭 시 테이블 삭제 대신 flag 수정
- 게시판 검색 시 삭제된 게시물은 검색되지 않도록 검색 조건 수정
<!-- 게시물 삭제 시 플래그 수정 -->
<delete id="updateBoardDelFlag" parameterType="Long">
UPDATE board
SET board_del = 1
WHERE board_seq = #{boardSeq}
</delete>
<!-- 검색 조건 수정 -->
<sql id="searchBoard">
<choose>
<when test="searchType != null and searchValue != null">
<choose>
<when test='searchType == "T"'>
WHERE (TITLE LIKE CONCAT('%',#{searchValue},'%')
AND BOARD_DEL = 0)
</when>
<when test='searchType == "C"'>
WHERE (CONTENTS LIKE CONCAT('%',#{searchValue},'%')
AND BOARD_DEL = 0)
</when>
<when test='searchType == "W"'>
WHERE (WRITER LIKE CONCAT('%',#{searchValue},'%')
AND BOARD_DEL = 0)
</when>
<when test='searchType == "A"'>
WHERE (TITLE LIKE CONCAT('%',#{searchValue},'%') OR CONTENTS LIKE CONCAT('%',#{searchValue},'%'))
AND BOARD_DEL = 0
</when>
<otherwise>
WHERE BOARD_DEL = 0
</otherwise>
</choose>
</when>
<otherwise>
WHERE BOARD_DEL = 0
</otherwise>
</choose>
</sql>
- dao 를 추가하고 삭제 dao 대신 updateBoardDelFlag 쿼리를 실행하도록 만든다
public int updateBoardDelFlag(Long boardSeq) {
return update("board.updateBoardDelFlag", boardSeq);
}
footer 하단에 고정시키기
2019-04-24 00:00:00 +0000footer 하단에 고정시키기
- footer를 하단에 고정시키지 않으면 contents의 내용이 끝나고 나서 바로 footer가 온다.
- contents의 길이가 어느정도 있도록 보여야 한다.
- footer에 absolute로 위치를 고정시키고 footer위 height 만큼 contents(본문)쪽에 bottom padding 을 준다
- css
html, body { margin:0; padding:0; height:100%; } .contents-wrap { min-height:100%; position:relative; padding-bottom:100px;/* footer height */ } .footer { width:100%; height:100px; position:absolute; bottom:0; background:#5eaeff; text-align: center; color: white; }
- html
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<link rel="stylesheet" type="text/css" href="/resources/css/common.css">
<script src="http://code.jquery.com/jquery-3.1.1.js"></script>
<sitemesh:write property='head' />
<!-- CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
</head>
<body>
<div class="container contents-wrap">
<div class="row">
<div class="top-menu-list pull-right">
<c:choose>
<c:when test="${not empty userVO.id}">
${userVO.name} 님 환영합니다
<span id="user-logout-button">로그아웃</span>
</c:when>
<c:otherwise>
<a href="/user/loginForm">로그인</a>
<a href="/user/createUserForm">회원가입</a>
</c:otherwise>
</c:choose>
</div>
</div>
<div class="row constants-top-menu">
<div class="col-md-3 col-xs-3"><a href="/main">메인화면</a></div>
<div class="col-md-3 col-xs-3"><a href="/board/list?page=1&count=10">게시판1</a></div>
<div class="col-md-3 col-xs-3">게시판2</div>
<div class="col-md-3 col-xs-3">게시판3</div>
</div>
<sitemesh:write property='body' />
<footer class="footer">
<div>Basic Board</div>
<div>@ 2019 wonhui Park</div>
<i class="fab fa-java fa-2x"></i><i class="fab fa-html5 fa-2x"></i><i class="fab fa-github-alt fa-2x"></i>
</footer>
</div>
<script type="text/javascript" src="/resources/js/common.js"></script>
</body>
</html>
LoginForm 만들 때 팁
- div로 배경화면에 색상을 넣어 LoginForm을 만들면 ui와 form의 여백이 없이 딱 맞게 만들어진다
- 공간이 있어야 하는데 bootstrap을 사용하면 flex가 많아서 padding, margin이 잘 안먹는다.
- 이럴 때 요소에 padding, margin 을 준다. 예를들어 button의 margin을 주면 margin만큼 여백이 들어선다
/**
- RECOMMENDED CONFIGURATION VARIA*BLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
- LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables/ / var disqus_config = function () { this.page.url = PAGE_URL; // Replace PAGE_URL with your page’s canonical URL variable this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page’s unique identifier variable }; */ (function() { // DON’T EDIT BELOW THIS LINE var d = document, s = d.createElement(‘script’); s.src = ‘https://parkwonhui.disqus.com/embed.js’; s.setAttribute(‘data-timestamp’, +new Date()); (d.head || d.body).appendChild(s); })(); </script>
bootstrap4 사용법
2019-04-23 00:00:00 +0000Bootstrap 정리
CDN
- head에 bootstrap을 추가하는 소스코드를 추가한다
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
모바일
- 모바일 환경에서 ui가 변경되어야 한다. 적절히 변경될 수 있도록 viewport 메타 태그를 추가한다
- viewport 태그는 모바일 폰에서의 크기 조절을 위해 만듬
- PC의 viewport는 웹 브라우저 창과 같음(크기 조절 가능)
- 모바일의 viewport는 웹 브라우저 창보다 작고 확대 축소로 뷰포트 배율 변경 가능
- 데스크탑에서 같은 px를 보더라도 pc에선 알맞게 나오지만 모바일에선 작게 나온다. 그렇기 때문에 viewport로 적절한 화면 배율을 설정해야 한다
<meta name="viewport" content="width=device-width, initial-scale=1">
Container
- body에 있는 모든 태그요소는 ‘container’ 안에 존재해야 한다.
- 만약 화면 너비 전체를 사용하고 싶다면 ‘.container-fluid’ class를 사용한다
<div class="container"></div>
Grid
- 크기에 따라 4가지 class 로 나뉜다
- 크기를 좀 더 늘리고 싶다면 맨 뒤의 숫자를 변경한다
col-lg-1 | col-md-1 | col-sm-1 | col-xs-1 |
---|---|---|---|
아주 큰 화면 | 중간 화면 | 작은 기기(태블릿) | 모바일 폰 |
<div class="row">
<div class="col-lg-1">큰 기기 테스크탑</div>
<div class="col-md-1">중간 기기 데스크탑</div>
<div class="col-xs-1">작은 기기 태블릿</div>
<div class="col-sm-1">매우 작은 기기 모바일폰</div>
</div>
- pc와 모바일의 요소의 비율을 다르게 하고 싶다면 각 각의 크기를 설정한다
- 아래 소스코드를 보면 첫번째 요소는 보통 pc화면에서는 (md) 크기가 4이고 두번째 요소도 마찬가지로 크기가 4이다. 그러므로 pc에서 두 요소는 5:5 비율이다
- 하지만 모바일에서 첫번째 요소는 크기가 12인데 두번째 요소2이다. 그래서 모바일로 보면 첫번째 요소와 두번째 요소의 크기가 다르다 ~~~
col-xs-12 col-md-8
col-xs-6 col-md-4
- 컬럼 오프셋 설정으로 몇 칸 띄어서 요소를 배치할 수 있다
- 예를 들어 <div class="col-md-4 col-md-offset-3">col-md-4</div> 라면 3칸 정도 띄운 후 해당 div 요소를 배치한다
col-md-4
col-md-4
### DataTable
- [DataTable](https://datatables.net/examples/styling/bootstrap4)
- DataTable 사용을 위해 아래 js를 추가한다
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap.min.js"></script> ~~~
- table 태그로 DataTable을 작성한다
- colgroup으로 순서대로 필드의 크기 비율을 설정한다
- thead 는 맨 위의 필드명을 뜻하고 tbody는 필드의 값을 뜻한다
<table id="board1-table" class="table table-striped table-bordred">
<colgroup>
<col width="10%" />
<col width="40%" />
<col width="10%" />
</colgroup>
<thead>
<tr>
<td>게시물 번호</td>
<td>게시물 제목</td>
<td>날짜</td>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1번 게시물</td>
<td>2019-4-12</td>
</tr>
<tr>
<td>2</td>
<td>2번 게시물</td>
<td>2018-4-12</td>
</tr>
<tr>
<td>3</td>
<td>3번 게시물</td>
<td>2018-4-13</td>
</tr>
</tbody>
</table>
Pagination
- pagination
- nav 태그는 html5에 등장한 태그. 현재 페이지에서 다른 페이지로 이동(탐색)을 수행할 때 사용한다. 메뉴 뿐 아니라 페이지네이션도 네비게이션에 해당한다
- li태그에 page-item 속성을 준다
- a태그에 class로 “page-link” 속성을 준다
- 현재 선택한 페이지 숫자와 동일하다면 태그에 active를 준다
<nav>
<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
selectForm
- form-control class 를 사용한다
- select box의 크기는 col-md-2, col-sm-1 등으로 정할 수 있다\
<select class="form-control col-sm-1 col-md-2 list-select-form" name="searchType">
<option value="A">전체</option>
<option value="T">제목</option>
<option value="C">내용</option>
<option value="W">작성자</option>
</select>
form 중앙정렬
- text-align:-webkit-center
- webkit 이란 크롬, 사파리 브라우저에 적용, -moz는 파이어폴스, -ms는 익스플로러를 뜻함
어썸 폰트
- 어썸폰트란 부트스트랩의 text 아이콘을 뜻한다. text이므로 이미지보다 가공하기 쉽고 깨지지 않는다
- 어썸폰트 공식 홈페이지
- 아래 style 추가 ~~~
- 사용방법
- fa-spin은 아이콘을 돌린다
- fa-fw는 공백 포함 넓이는 고정하여 깔끔해보이도록 함
- fa-3x는 크기 변경
~~~
Spring 데이터 검증 @Valid, BindingResult
2019-04-22 00:00:00 +0000Spring 데이터 검증 @Valid, BindingResult
데이터 검증
- @Valid는 객체에 들어가는 값을 검증해주는 어노테이션이다
- 유효한 값인지 검증은 소스코드 여러군데서 이루어지기 때문에 불필요한 중복코드가 늘어나고 복잡하다.
- @Valid를 사용하면 @Min,@Max,@NotNull 등의 어노테이션으로 간단하게 값을 체크할 수 있다
- @@Valid 어노테이션을 사용하는 방법, BindingResult를 사용하는 방법 두가지로 나뉜다.
@Valid 어노테이션 사용
- validation-api 가 아닌 hibernate-validator 를 추가해야한다.
- validation-api 라이브러리를 사용하게 되면 @Range, @NotNull, @Size 등.. 의 어노테이션으로 검증이 불가하다
- validation-api 를 사용하면 Validator를 상속하는 유효검증 클래스를 만든 후 검증을 구현해야한다(아래에 설명)
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
model 선언
- @NotEmpty 은 null과 ““는 비허용하고 “ “ 띄어쓰기는 허용한다
- @Size와 @Range 어노테이션은 값이 지정한 범위내로 들어올 때만 값을 넣어준다
- @message는 에러가 발생할 시 defaultText로 지정할 수 있다
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range;
public class UserInfo {
@NotEmpty(message="name을 입력해주세요")
private String name;
@NotEmpty(message="비밀번호를 입력해주세요")
@Size(min = 6, max=10, message = "길이가 알맞지 않습니다")
private String password;
@Range(min = 1, max = 5)
private int grade;
public UserInfo() {}
@Override
public String toString() {
return "User [name=" + name + ", password=" + password + ", grade=" + grade + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
Contorller 선언
- view에 전달받은 값에 @Valid나 @Validated 어노테이션을 붙인다.
- 에러 체크는 hasErrors 함수를 사용한다
- 에러 리스트는 getAllErrors() 함수로 가져온다
- getDefaultMessage()함수로 defaultError 메시지를 가져올 수 있다
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import my.test.model.UserInfo;
@Controller
public class UserController {
@RequestMapping(value="/joinForm", method=RequestMethod.GET)
public String joinForm(){
return "join";
}
@RequestMapping(value="/join", method=RequestMethod.POST)
public String join(@Validated UserInfo userInfo, BindingResult bindingResult){
System.out.println("name:"+userInfo.getName());
System.out.println("pass:"+userInfo.getPassword());
System.out.println("error:"+bindingResult.hasErrors());
if(bindingResult.hasErrors()){
List<ObjectError> list = bindingResult.getAllErrors();
for(ObjectError e : list) {
System.out.println(e.getDefaultMessage());
}
return "join";
}
return "home";
}
}
View 선언
- UserInfo 에 들어갈 값을 전달하는 화면을 구성한다.
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<form action="/join" method="post">
<label>이름:</label>
<input name="name" type="text" id="name">
<label>비밀번호:</label>
<input name="password" type="password" id="password">
<input type="submit" value="전송">
</form>
</body>
</html>
BindingResult를 사용
- Validator를 상속받는 클래스에서 객체값을 검증하는 방식이다
- hibernate-validator 가 아닌 validation-api 라이브러리를 사용한다
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
model 선언
- 검증 클래스를 따로 만들어서 거기서 유효값을 체크한다. 그래서 @Min, @Max 등의 어노테이션을 사용하지 않는다
public class UserInfo {
private String name;
private String password;
public UserInfo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
validator 선언
- 객체를 검증할 validator 클래스를 생성
- Validator를 인터페이스 상속 후 supports, validate 함수를 재정의 한다.
- validate 함수에서 값이 유효한지 체크한다.
package test.controller;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import test.VO.UserInfo;
public class UserInfoValidator implements Validator{
public UserInfoValidator() {
}
@Override
public boolean supports(Class<?> clazz) {
return UserInfo.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
UserInfo userInfo = (UserInfo) target;
String mName = userInfo.getName();
if(null == mName || mName.trim().isEmpty()) {
System.out.println("회원이름을 이름하세요");
errors.rejectValue("name", "공백");
}
String password = userInfo.getPassword();
if(null == password || password.trim().isEmpty()) {
System.out.println("회원 비밀번호를 입력하세요");
errors.rejectValue("password", "공백");
}
}
}
Contorller 선언
- UserInfo값을 받을 때 BindingResult 객체의 값도 받습니다.
- join url에 호출될 때 마다 initBinder 함수가 호출되면서 UserInfoValidator 객체를 생성한 후 해당 객체의 validate 함수를 호출해서 값이 유효한지 체크한다
- bindingResult.hasErrors() 함수로 값이 알맞은지 체크할 수 있다.
- View는 위 예제와 동일하다
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import lombok.extern.log4j.Log4j;
import test.VO.UserInfo;
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
@GetMapping(path = "/joinForm")
public String joinForm(){
return "join";
}
@PostMapping(path = "/join")
public String join(@Validated UserInfo userInfo, BindingResult bindingResult){
System.out.println("name:"+userInfo.getName());
System.out.println("pass:"+userInfo.getPassword());
System.out.println("error:"+bindingResult.hasErrors());
if(bindingResult.hasErrors()){
return "join";
}
return "home";
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new UserInfoValidator());
}
}
Valid방식과 BindingResult 방식
- @Valid 방식을 사용하면 유효범위값을 쉽게 체크할 수 있다. BindingResult도 유효범위를 체크하지만 직접 유효범위 체크 코드를 추가해야하므로 @Valid 방식이 좀 더 사용하기 편했다. BindingResult는 일반적으로 유효값을 체크하는 방식보다는 더 간편하고 깔끔하다.
brackets 실시간 미리보기
2019-04-22 00:00:00 +0000Brackets(브라켓) 실시간 미리보기
- Brackets 에디터에서 실시간으로 변경된 사항이 적용되는 기능을 사용하고 싶어 설치하게 되었다.
- f5를 누르지 않아도 화면 그대로 적용이 된다
Brackets 다운로드
- Brackets 다운로드
- Brackets 실행 후 파일 - 실시간 미리보기 (ctrl+alt+p)
에러발생
- 파일을 저장하는 동안 에러가 발생했습니다
- 파일…을 저장하던 와중에 에러가 발생했습니다. 파일을 수정할 수 있는 권한이 없습니다.
- 파일의 이름을 변경하던 중에 에러가 발생했습니다
파일 /_brackets_88091691/제목없음의 이름을 변경하던 중에 에러가 발생했습니다. The file or directory is not part of the currently opened project.
Unfortunately, only project files can be renamed at this point.
- 권한이 없어서 저장하지 못하는 에러가 발생했다. 이 에러는 관리자 권한으로 실행해서
Posts
Interceptor(인터셉터)
Android Studio Install
계층형 게시판
VirtualBox Ubuntu 18.04.2 LTS
TransactionAwareDataSourceProxy Error
Java Coding Conventions
Java Long과 long의 차이
Mybatis 객체 안에 객체 매핑
JavaConfig mariadb 연결
DataTable
관리자 페이지
MappingJackson2JsonView
Spring Javaconfig
게시판 만들기-제품 등록
게시판 만들기-제품 페이지 제작
게시판 만들기-회원탈퇴 및 게시판 삭제 플래그 추가
footer 하단에 고정시키기
bootstrap4 사용법
Spring 데이터 검증 @Valid, BindingResult
brackets 실시간 미리보기
Spring 기본설정(pom.xml, web.xml, encoding)
Vue.js computed, methods, watch
javascript onkeyup
Maria DB Incorrect string value Error
javascript 암호화(md5, base64)
Vue.js template
Vue.js 소개
Nexacro 설명
ControllerAdvice
Batch
html 페이지 로딩 순서
소수구하기(PrimeNumber)
최소공배수,최대공약수
Stream
Lambda(람다식)
inner class(내부 클래스)
final 키워드
file upload
파이썬 빅 데이터 K-평균(K-means)
아나콘다(Anaconda), 주피터 개발환경 세팅
텐서플로우(TensorFlow) 아키텍쳐 및 Session
텐서플로우(TensorFlow)상수, 변수, 함수
머신러닝 기초
한글 리스트 오름차순, 내림차순
연속된 글자의 갯수 출력
java spring5 프로젝트 설정
restController
spring 세팅 및 기본설정
mybatis trim
jquery datepicker
ajax로 데이터 전달/응답 받는법
mybatis error
mybatis 게시판 만들기 순서
Java Jsp Mybatis Dynamic Query
mybatis
git 소개
node.js 개발환경 구축
node.js 기본 내장 모듈
node.js의 전역 객체
node.js http module
node.js event
jdbc
자바빈
jsp, servlet 정리
java null object pattern
다음지도 key 등록(kakao map)
공공 데이터 open api
facebook login api
sourcetree 사용법
JavaScript event3
JavaScript jquery
JavaScript dom
JavaScript ajax
JavaScript 이벤트2
JavaScript 캡슐화
JavaScript Array,내장객체
JavaScript var
JavaScript 객체,생성자
JavaScript 함수,클로저
JavaScript Event
javascript eclipse 자동완성(with tern)
CSS position
HTML5,CSS 선택자
자바 시간 측정
git,eclipse 연동
HTML 기초 정리
Eclipse Web 환경세팅
피보나치의 수
Oracle 반복문,커서,예외,저장 서브프로그램
Oracle PL/SQL
Oracle 다중쿼리(Multiple row query)
Oracle 인덱스, 뷰, 시퀀스, 트랜잭션, 세션 정리
Oracle JOIN 정리
Oracle DDL, DML 정리
Oracle 문자열 함수 정리
Oracle 숫자,날짜,자료형 변환 함수 정리
Oracle 제약조건 정리
Oracle 기초 쿼리 정리
문제2775
DFS
junit
json
algorithmus basic
circular queue(원형큐)
binary search(이진탐색)
port forwarding(포트포워딩)
kakao chatbot(카카오 챗봇)
java io
sort comparable, comparator
Unresolved compilation problem
ArrayList, HashMap
Regular(정규표현식)
Enum Class
String Function
refactoring 이란(상수,제어플래그,assert)
reference,abstract 정리
FileNotFoundException Solve
static
Thread Synchronization(스레드동기화,원자성)
Java Exception(예외처리)
Java 생성자, this, super
roomnum
BeeHouse
Git Reset, Revert
Git Log
Array
stack
pyramid draw
Star Draw(별 그리기4)
Star Draw(별 그리기3)
Star Draw(별 그리기2)
Star Draw(별 그리기1)
Loop(While, For)
자바 데이터 타입, 데이터 연산
시계방향 달팽이 그리기
정수값의 짝수,홀수 갯수 구하기
java, Scanner 정리
draw dog
subscribe via RSS