Properties 활용
- Spring에서는 주요 정보를 properties 파일에 저장해놓거나 불러와서 사용할 수 있음
- Xml이나 properties는 정보를 컴파일하지 않기 때문에 쉽게 읽고 수정이 가능
- 보안성은 좋지 않음
Login Service(관리자 아이디 부여)
- application.properties
- 127.0.0.1 : 내 서버 ip
# super user
user.id=superAdmin
user.pw=pass@Goodee
user.ip=127.0.0.1
server.port=80
# encoding
server.servlet.encoding.charset=utf-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
# logger
logging.level.root=info
# jsp
spring.mvc.view.prefix=/views/
spring.mvc.view.suffix=.jsp
# jdbc
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
# add log4jdbc
spring.datasource.url=jdbc:log4jdbc:mariadb://localhost:1512/mydb
spring.datasource.username=web_user
spring.datasource.password=pass
# mapper
mybatis.mapper-locations=mapper/*_mapper.xml
- MemberController
package kr.co.gudi.controller;
import javax.servlet.http.HttpServletRequest;
import kr.co.gudi.service.MemberService;
@RestController
public class MemberController {
@Autowired MemberService service;
Logger logger = LoggerFactory.getLogger(getClass());
// RestController에서 jsp파일로 이동하고 싶을 때는 ModelAndView를 사용하면 이동가능
@RequestMapping(value = "/")
public ModelAndView main() {
return new ModelAndView("login");
}
@PostMapping(value = "/login.do")
public ModelAndView login(String id, String pw,HttpServletRequest req) {
String ip = req.getRemoteAddr();
logger.info("remote ip : "+ip); // remote ip : 0:0:0:0:0:0:0:1 <- IPV6
return service.login(id,pw,ip,req.getSession());
}
}
- MemberService(DB 로그인 생략)
package kr.co.gudi.service;
import javax.servlet.http.HttpSession;
import kr.co.gudi.dao.MemberDAO;
@Service
public class MemberService {
@Autowired MemberDAO dao;
// properties에 있는 값 가져오기
@Value("${user.id}") private String adminId;
@Value("${user.pw}") private String adminPw;
@Value("${user.ip}") private String adminIp;
Logger logger = LoggerFactory.getLogger(getClass());
public ModelAndView login(String id, String pw, String ip, HttpSession session) {
logger.info(id+" / "+pw);
// 특정한 ID로 로그인 시도 시 일반 DB를 통한 로그인을 하지 않음
logger.info(adminId+" / "+adminPw+" / "+adminIp);
String page = "redirect:/";
String msg = "로그인에 실패했습니다.";
if(id.equals(adminId)) {
// 관리자 로그인 진행
if(pw.equals(adminPw) && ip.equals(adminIp)) {
page = "result";
msg = "로그인에 성공했습니다.";
session.setAttribute("loginId", id);
session.setAttribute("ip", ip);
session.setAttribute("grade", "admin");
}
}else {
// DB를 이용한 일반 로그인 진행
if(dao.login(id,pw) == 1) {
page = "result";
msg = "로그인에 성공했습니다.";
session.setAttribute("loginId", id);
session.setAttribute("ip", ip);
session.setAttribute("grade", "user");
}
}
ModelAndView mav = new ModelAndView(page);
mav.addObject("msg",msg);
return mav;
}
}
AOP(Aspect Oriented Programming)
- 관점 지향 프로그래밍
- 하나의 흐름에 특정한 시점에 수행되는 프로그램을 만드는 것

Interceptor
- Interceptor를 활용하면 Controller 도착 전 특정 작업을 수행하거나 Controller를 지나 client에 도착하기 전 특정 작업을 수행 할 수 있음
- Spring boot 2.6.x 부터는 Interceptor를 활용하기 위해서 아래의 Interface를 구현받아야 함(controller 생성시)
- org.springframework.web.servlet.HandlerInterceptor
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
- org.springframework.web.servlet.HandlerInterceptor
- InterceptorConfig(config package 생성)
package kr.co.gudi.config;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import kr.co.gudi.utils.LoginCheck;
@Configuration // 이게 있어야 설정 클래스라는 의미
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired LoginCheck check;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry에 인터셉트 할 내용이 들어감
ArrayList<String> excludeList = new ArrayList<String>();
excludeList.add("/");
excludeList.add("/join*"); // join 뒤에 뭐가 오는 경우 예외
excludeList.add("/resources/**"); // resources/ 이후 모든 경로들 예외
excludeList.add("/*.ajax"); // .ajax로 끝나는 요청은 예외
registry.addInterceptor(check) // 실행할 클래스
.addPathPatterns("/**") // 인터셉트를 적용할 URL pattern
.excludePathPatterns(excludeList); // 예외 패턴
}
}
- LoginCheck(utils 생성)
package kr.co.gudi.utils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class LoginCheck implements HandlerInterceptor {
Logger logger = LoggerFactory.getLogger(getClass());
// preHandler : Controller 전에 이곳을 지나침
// true : 컨트롤러 접근 허용 / false : 컨트롤러 접근 불가
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("preHandler : "+request.getRequestURI());
boolean pass = true;
HttpSession session = request.getSession();
if(session.getAttribute("loginId") == null) {
response.sendRedirect("/");
pass = false;
}
return pass;
}
// postHandler : 컨트롤러를 지나간 이후 들림
// request / response 객체에 추가로 담아서 보낼때
// xxxModelAndView에 무언가 추가할 때
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView mav) throws Exception {
logger.info("postHandler");
String loginId = (String) request.getSession().getAttribute("loginId");
String content = "<div>안녕하세요 "+loginId+"님 <a href='logout.do'>로그아웃</a></div>";
mav.addObject("loginBox",content);
}
}
Aspect-J
- Aspect-J : point cut 표현식을 사용해서 특정 메서드 사용 전후에 처리를 도와주는 라이브러리
- Spring에서는 이 기능을 활용하기 위해 최소 3가지 라이브러리가 필요하지만 Boot에서는 하나의 라이브러리만 설정하면 됨
- 프로젝트 만들기 까다로워? 생략
'코딩도전기 > Spring Boot' 카테고리의 다른 글
Spring Boot - Scheduler / File Upload&Download (0) | 2023.06.07 |
---|---|
Spring Boot - REST API (0) | 2023.05.31 |
String Boot - Restful Service (0) | 2023.05.30 |
Spring Boot - Transaction / Connection Pool / CSS 일괄적용 (0) | 2023.05.26 |
Spring Boot - 쿼리문 로고 찍기 / 동적쿼리 (0) | 2023.05.25 |