728x90
join.jsp
<%@ 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" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사용자 등록</title>
</head>
<body>
<h2>사용자 등록</h2>
<form:form modelAttribute="user" method="post" action="join">
<spring:hasBindErrors name="user">
<font color="red">
<c:forEach items="${errors.globalErrors}" var="error">
<spring:message code="${error.code}" /><br/>
</c:forEach>
</font>
</spring:hasBindErrors>
<table>
<tr>
<td>아이디</td>
<td>
<form:input path="userid" />
<font color="red"><form:errors path="userid" /></font>
</td>
</tr>
<tr>
<td>비밀번호</td>
<td>
<form:input path="password" />
<font color="red"><form:errors path="password" /></font>
</td>
</tr>
<tr>
<td>이름</td>
<td>
<form:input path="username" />
<font color="red"><form:errors path="username" /></font>
</td>
</tr>
<tr>
<td>전화번호</td>
<td><form:input path="phoneno" /></td>
</tr>
<tr>
<td>우편번호</td>
<td><form:input path="postcode" /></td>
</tr>
<tr>
<td>주소</td>
<td><form:input path="address" /></td>
</tr>
<tr>
<td>이메일</td>
<td>
<form:input path="email" />
<font color="red"><form:errors path="email" /></font>
</td>
</tr>
<tr>
<td>생년월일</td>
<td>
<form:input path="birthday" />
<font color="red"><form:errors path="birthday" /></font>
</td>
</tr>
<tr>
<td><input type="submit" value="회원가입"></td>
<td><input type="reset" value="초기화"></td>
</tr>
</table>
</form:form>
</body>
</html>
logic/User.java
@Data
public class User {
@Size(min=3, max=10, message="아이디는 3자이상 10자 이하로 입력하세요")
private String userid;
private String channel;
@Size(min=3, max=10, message="비밀번호는 3자이상 10자 이하로 입력하세요")
private String password;
@NotEmpty(message="사용자 이름은 필수 입니다")
private String username;
private String phoneno;
private String postcode;
private String address;
@NotEmpty(message="email을 입력하세요")
@Email(message="email 형식으로 입력하세요")
private String email;
// @NotNull(message="생일을 입력하세요") 필수입력
@Past(message="생일은 과거 날짜만 가능합니다")
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
}
service/UserService
@Service
public class UserService {
@Autowired
UserDao userdao;
public void userInsert(User user) {
userdao.insert(user);
}
}
controller/UserController
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private UserService service;
@GetMapping("*") // Get 방식 모든 요청호출
public ModelAndView form() {
ModelAndView mav = new ModelAndView();
mav.addObject(new User());
return mav; // url과 연동된 뷰를 호출
}
@PostMapping("join")
//BindingResult은 입력값 검증대상 변수의 다음에 와야함
public ModelAndView userAdd(@Valid User user, BindingResult bresult) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) {
// 추가 오류 메세지 등록
bresult.reject("error.input.user");
bresult.reject("error.input.check");
return mav;
}
// 정상적으로 입력된 경우
try {
service.userInsert(user);
}catch (DataIntegrityViolationException e) { // (아이디 중복)
e.printStackTrace();
bresult.reject("error.duplicate.user");
return mav;
} catch (Exception e) {
e.printStackTrace();
return mav;
}
mav.setViewName("redirect:login");
return mav;
}
}
config/MvcConfig
utf-8설정해야된다
@Bean // 메세지를 코드값으로 처리하기 위한 설정
public MessageSource messageSource() {
ResourceBundleMessageSource ms = new ResourceBundleMessageSource();
ms.setBasename("messages"); // messages.properties로 설정
ms.setDefaultEncoding("UTF-8");
return ms;
}
resources/messages.properties
typeMismatch.birthday=생년월일은 YYYY-MM-DD 형식으로 입력해 주세요
error.input.user=회원 가입 정보 입력 오류 입니다.
error.input.check=입력 정보를 확인하세요.
error.duplicate.user=중복된 아이디 입니다.
error.login.input=입력 데이터 오류 입니다.
error.login.id=아이디를 확인하세요
error.login.password=비밀번호 오류입니다.
error.required.userid=아이디는 3자이상 10자 이하로 입력하세요
error.required.password=비밀번호는 3자이상 10자 이하로 입력하세요

dao/UserDao
@Repository
public class UserDao {
@Autowired
private SqlSessionTemplate template;
private Map<String, Object> param = new HashMap<>();
private Class<UserMapper> cls = UserMapper.class;
public void insert(User user) {
template.getMapper(cls).insert(user);
}
}
dao/mapper/UserMapper
public interface UserMapper {
@Insert("insert into useraccount "
+ "(userid,username,password,birthday,phoneno,postcode,address,email)"
+ "values (#{userid},#{username},#{password},#{birthday},#{phoneno},#{postcode},#{address},#{email})")
void insert(User user);
}
로그인
user/login
<%@ 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="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인화면</title>
<script type="text/javascript">
function win_open(page){
var op = "width=500, height=350, left=50, top=150";
open(page,"",op);
}
</script>
</head>
<body>
<h2>사용자 로그인</h2>
<form:form modelAttribute="user" method="post" action="login" name="loginform">
<spring:hasBindErrors name="user">
<font color="red">
<c:forEach items="${errors.globalErrors}" var="error">
<spring:message code="${error.code}" />
</c:forEach>
</font>
</spring:hasBindErrors>
<table>
<tr>
<td>아이디</td>
<td>
<form:input path="userid"/>
<font color="red">
<form:errors path="userid" />
</font>
</td>
</tr>
<tr>
<td>비밀번호</td>
<td>
<form:password path="password"/>
<font color="red">
<form:errors path="password" />
</font>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="로그인">
<input type="submit" value="회원가입" onclick="location.href='join'">
<input type="submit" value="아이디찾기" onclick="win_open('idsearch')">
<input type="submit" value="비밀번호찾기" onclick="win_open('pwsearch')">
</td>
</tr>
</table>
</form:form>
</body>
</html>
controller/UserController
/*
1. userid 맞는 User를 db에서 조회하기
2. 비밀번호 검증
일치 : session.setAttribute("loginUser", dbUser) => 로그인 정보
불일치 : 비밀번호를 확인하세요. 출력 (error.login.password)
3. mypage로 페이지 이동 => 404 오류 발생 (임시)
*/
@PostMapping("login")
public ModelAndView login(User user, BindingResult bresult, HttpSession session) {
if(user.getUserid().trim().length() < 3 ||user.getUserid().trim().length() > 10) {
// @Valid 어노테이션에서 등록방식으로 처리
// messages.properties 파일에 : error.required.userid로 메세지 등록
bresult.rejectValue("userid", "error.required");
}
if(user.getPassword().trim().length() < 3 ||user.getPassword().trim().length() > 10) {
bresult.rejectValue("password", "error.required");
}
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) { // 등록된 오류 존재?
// global error 등록
bresult.reject("error.input.check");
return mav;
}
User dbUser = service.selectUser(user.getUserid());
if(dbUser == null) { // 아이디 없음
bresult.reject("error.login.id");
return mav;
}
if(user.getPassword().equals(dbUser.getPassword())) { // 비밀번호 일치
session.setAttribute("loginUser", dbUser);
mav.setViewName("redirect:mypage?userid=" + user.getUserid());
}else { // 비밀번호 오류시
bresult.reject("error.login.password");
return mav;
}
return mav;
}
service/UserService
public User selectUser(String userid) {
return userdao.selectOne(userid);
}
UserDao
dao.mapper gpt 돌려서 해석받기
public User selectOne(String userid) {
param.clear();
param.put("userid", userid);
return template.selectOne("dao.mapper.UserMapper.select",param);
}
UserMapper
@Select({"<script>",
"select * from useraccount ",
"<if test='userid != null'> where userid=#{userid}</if>",
"</script>"})
List<User> select(Map<String, Object> param);
마이페이지
user/mypage
<%@ 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>
<head>
<meta charset="UTF-8">
<title>Mypage</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#minfo").show()
$("#oinfo").hide()
$(".saleLine").each(function(){
$(this).hide()
})
$("#tab1").addClass("select")
})
function disp_div(id, tab){
$(".info").each(function(){
$(this).hide()
})
$(".tab").each(function(){
$(this).removeClass("select")
})
$("#" + id).show()
$("#" + tab).addClass("select")
}
function list_disp(id){
$("#" + id).toggle()
}
</script>
<style type="text/css">
.select{paddong:3px; background-color:#0000ff;}
.select > a{color:#fff; text-decoration: none; font-weight: bold;}
.title{text-decoration: none;}
</style>
</head>
<body>
<table>
<tr>
<td id="tab1" class="tab">
<a href="javascript:disp_div('minfo', 'tab1')" class="title">회원정보</a>
</td>
<c:if test="${param.userid != 'admin' }">
<td id="tab2" class="tab">
<a href="javascript:disp_div('oinfo', 'tab2')" class="title">주문정보</a>
</td>
</c:if>
</tr>
</table>
<div id="oinfo" class="info" style="display:none; width:100%;">
<table>
<tr>
<th>주문번호</th>
<th>주문일자</th>
<th>주문금액</th>
</tr>
<c:forEach items="${salelist}" var="sale" varStatus="stat">
<tr>
<td align="center">
<a href="javascript:list_disp('saleLine${stat.index}')">${sale.saleid }</a>
</td>
<td align="center">
<fmt:formatDate value="${sale.saledate }" pattern="yyyy-MM-dd" />
</td>
<td align="center">
<fmt:formatDate value="${sale.total }" pattern="###,###" />원
</td>
</tr>
<tr id="saleLine${stat.index }" class="saleLine">
<td colspan="3" align="center">
<table>
<tr>
<td>상품명</td>
<td>상품가격</td>
<td>주문수량</td>
<td>상품총액</td>
</tr>
<c:forEach items="${sale.itemList}" var="saleItem">
<tr>
<td class="title">${saleItem.item.name }</td>
<td><fmt:formatNumber value="${saleItem.item.price } pattern="###,###" />원</td>
</tr>
</c:forEach>
</table>
</td>
</tr>
</c:forEach>
</table>
</div>
<div id="minfo" class="info">
<table>
<tr><td>아이디</td><td>${user.userid }</td></tr>
<tr><td>이름</td><td>${user.username}</td></tr>
<tr><td>우편번호</td><td>${user.postcode}</td></tr>
<tr><td>전화번호</td><td>${user.phoneno }</td></tr>
<tr><td>이메일</td><td>${user.email }</td></tr>
<tr>
<td>생년월일</td>
<td><fmt:formatDate value="${user.birthday}" pattern="yyyy-MM-dd" /></td>
</tr>
</table>
<br/>
<a href="logout">[로그아웃]</a>
<a href="update?userid=${user.userid}">[회원정보수정]</a>
<a href="password">[비밀번호수정]</a>
<c:if test="${loginUser.userid != 'admin' }">
<a href="delete?userid=${user.userid}">[회원탈퇴]</a>
</c:if>
<c:if test="${loginUser.userid == 'admin' }">
<a href="../admin/list">[회원목록]</a>
</c:if>
</div>
</body>
</html>
controller/UserController
/*
AOP 설정필요 : UserLoginAspect 클래스의 userIdCheck 메서드로 구현
1. 로그인여부 검증
로그아웃상태인 경우 로그아웃 후 거래 메세지 출력. login 페이지로 이동
2. 본인 거래 여부 검증
admin이 아니면서 다른 사용자 정보 출력 불가
*/
// (마이페이지)
@RequestMapping("mypage")
public ModelAndView idCheckmypage(String userid, HttpSession session) {
ModelAndView mav = new ModelAndView();
User user = service.selectUser(userid);
mav.addObject("user", user);
return mav;
}
// (로그아웃)
@RequestMapping("logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:login";
}
스프링 예외처리
MvcConfig
aop 추가
@EnableAspectJAutoProxy // AOP 사용을 위한 설정
@ComponentScan(basePackages= {"controller", "logic", "service", "dao", "aop"})
pom.xml
@Aspect 어노테이션을 사용하기위해서 라이브러리 설치
<!-- AOP 관련 설정 -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
exception/ShopException
RuntimeException : 나는 예외처리 안해도되
@Getter
public class ShopException extends RuntimeException {
private String url;
public ShopException(String msg, String url) {
super(msg);
this.url = url;
}
}
aop/UserLoginAspect
로그인 검증이 필요한 컨트롤러 이름 앞에 idCheck 붙여주기
@Around("execution(* controller.User*.idCheck*(..)) && args(..,userid,session)") 양식에 맞는 메서드
알아서 로그인 검증하여 오류메세지 출력
/*
1. pointcut : UserControlle.idCheck* 메서드로 시작하고, 마지막 매개변수가 String(userid), HttpSession 인 메서드를 설정
2. advice : Around로 이용
*/
@Component
@Aspect
public class UserLoginAspect {
@Around("execution(* controller.User*.idCheck*(..)) && args(..,userid,session)")
public Object userIdCheck(ProceedingJoinPoint joinPoint, String userid, HttpSession session) throws Throwable{
User loginUser = (User) session.getAttribute("loginUser");
if(loginUser == null || !(loginUser instanceof User)) { // 로그아웃 상태, 유저객체가 아닌경우 발동
throw new ShopException("[idCheck] 로그인이 필요합니다.", "login");
}
if(!loginUser.getUserid().equals("admin") && !loginUser.getUserid().equals(userid)) {
throw new ShopException("[idCheck] 본인 정보만 거래 가능합니다.", "../item/list");
}
return joinPoint.proceed();
}
}
MvcConfig
오류발생시 500에러 발생 + 에러 메세지 출력
-
-
@Bean // 예외처리 객체
public SimpleMappingExceptionResolver exceptionHandler() {
SimpleMappingExceptionResolver ser = new SimpleMappingExceptionResolver();
Properties pr = new Properties();
// 에러 발생시 exception 페이지로 전달
pr.put("exception.ShopException", "exception");
ser.setExceptionMappings(pr);
return ser;
}
view/exception
에러페이지 발생x 알림창으로 에러 메세지 발동
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true" %>
<%-- isErrorPage="ture" : ShopException 객체가 전달됨 --%>
<script>
alert("${exception.message}")
location.href="${exception.url}"
</script>
728x90
'SpringBoot' 카테고리의 다른 글
| [BCGD] 비전공자 백엔드 개발 도전기 (71) (1) | 2025.06.10 |
|---|---|
| [BCGD] 비전공자 백엔드 개발 도전기 (70) (0) | 2025.06.10 |
| [BCGD] 비전공자 백엔드 개발 도전기 (66) (0) | 2025.06.10 |
| [BCGD] 비전공자 백엔드 개발 도전기 (65) (0) | 2025.06.10 |
| [BCGD] 비전공자 백엔드 개발 도전기 (64) (0) | 2025.06.10 |
