스프링21_종합2, 파일처리, 에러 처리

404에러

  • 404를 처리하는 방법 2가지
    -> ✨✨filter, web.xml 수정


자바

HomeController

@Controller
public class HomeController {

	@RequestMapping("/")
	public String home() {
		return "home";
	}
}

MemberContorller


@Controller
@RequestMapping("member")
public class MemberController {
	
	@Autowired
	private MemberService service;

	//로그인 화면 보여주기
	@GetMapping("login")
	public String login() {
		return "member/login";
	}
	
	//로그인 로직 처리
	@PostMapping("login")
	public String login(MemberDto dto) {
		return "member/login";
	}
	
	//회원가입 화면 보여주기
	@GetMapping("join")
	public String join() {
		return "member/join";
	}
	
	//회원가입 로직 처리
	@PostMapping("join")
	public String join(MemberDto dto) throws Exception {
		System.out.println(dto);
		
//		int result = service.join(dto);
		return "member/join";
	}
}



MemberDto

@Data
public class MemberDto {

	private long userNo;
	private String userId;
	private String userPwd;
	private String userNick;
	private int userAge;
	private String userGender;
	private String userProfile;
	private MultipartFile f;
	private String changeName;
}


MemberService 인페

public interface MemberService {

	int join(MemberDto dto) throws Exception;
}


MemberServiceImpl


@Service
@Slf4j
@Transactional
public class MemberServiceImpl implements MemberService {

	@Autowired
	private MemberDao dao;
	
	@Override
	public int join(MemberDto dto) throws Exception{
		//회원가입 처리
		
		//회원번호, 시퀀스 nextval
		int no = dao.getMemberSeq();
		//insert 처리
		dto.setUserNo(no);
		log.info(dto.toString());
		int result = dao.insertMember(dto);
		
		
		//////////////////////
		
		//파일 업로드(우리 서버에)
		MultipartFile f = dto.getF();
		
		if(!f.isEmpty()) {
			//원래 이름	-> db에 저장
			//변경된 이름 -> db에 저장
			//서비스 레이어에서 작업하도록
			String changeName = System.currentTimeMillis()+"_"+f.getOriginalFilename();
			dto.setChangeName(changeName);
			//사이즈, 타입
			System.out.println("===============");
			System.out.println(f.getOriginalFilename());
			System.out.println(f.getSize());
			System.out.println(f.getContentType());
			System.out.println("===============");
			
			//파일을 서버에 저장
			File file = new File("D:/uploadForSpring/999prj/profile/"+ f.getOriginalFilename());
			f.transferTo(file);
			
			//db에 insert
			dao.uploadProfile(dto);
		}
		
		return result;
	}

}


MemberDao 인페

public interface MemberDao {
	
	int getMemberSeq() throws Exception;

	int insertMember(MemberDto dto) throws Exception;

	void uploadProfile(MemberDto dto) throws Exception;

}


MemberDaoImpl

@Repository
public class MemberDaoImpl implements MemberDao{

	@Autowired
	private SqlSession sqlSession;
	
	
	@Override
	public int getMemberSeq() throws Exception {
		return sqlSession.selectOne("member.getSeq");
	}

	@Override
	public int insertMember(MemberDto dto) throws Exception{
		return sqlSession.insert("member.insertMember", dto);
	}

	@Override
	public void uploadProfile(MemberDto dto) throws Exception {
		sqlSession.insert("member.insertProfile", dto);
	}
	
}


member-mapper.xml

<mapper namespace="member">

	<select id="getSeq" resultType="int">
		SELECT MEMBER_SEQ.NEXTVAL FROM DUAL
	</select>
	
	<insert id="insertMember" parameterType="memberDto">
		INSERT INTO MEMBER
		(
			 USER_NO 
		    ,USER_ID
		    ,USER_PWD 
		    ,USER_NICK 
		    ,USER_AGE   
		    ,USER_GENDER 
		    ,USER_PROFILE
		)
		VALUES
		(
			#{userNo}
			,#{userId}
			,#{userPwd}
			,#{userNick}
			,#{userAge}
			,#{userGender}
			,#{userProfile}
		)
		
	</insert>

 	<insert id="insertProfile" parameterType="memberDto">
 		INSERT INTO MEMBER_PROFILE
 		(
 		    FILE_NO
		    ,USER_NO
		    ,CHANGE_NAME
 		)
 		VALUES
 		(
 			 MEMBER_PROFILE_SEQ.NEXTVAL
 			 ,#{userNo}
 			 ,#{changeName}
 		)
 	
 	</insert>  
  
</mapper>


mybatis-config.xml

<configuration>
	<settings>
		<setting name="cacheEnabled" value="true"/>
		<setting name="autoMappingBehavior" value="FULL"/>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="jdbcTypeForNull" value="NULL"/>
	</settings>
	<!-- 경로의 별칭 지정 -->
	
	<typeAliases>
		<typeAlias type="com.kh.app999.member.entity.MemberDto" alias="memberDto"/>
	
	</typeAliases> 
	
</configuration>



디비

MEMBER

drop table member;
CREATE TABLE MEMBER(
    USER_NO NUMBER PRIMARY KEY
    ,USER_ID VARCHAR2(100)
    ,USER_PWD VARCHAR2(100)
    ,USER_NICK VARCHAR2(100)
    ,USER_AGE   NUMBER
    ,USER_GENDER    CHAR(1)
    ,USER_PROFILE   VARCHAR2(500)
);

DROP SEQUENCE MEMBER_SEQ;
CREATE SEQUENCE MEMBER_SEQ NOCACHE NOCYCLE;

COMMIT;
SELECT * FROM MEMBER;

SELECT MEMBER_SEQ.NEXTVAL FROM DUAL;


MEMBER_PROFILE

DROP TABLE MEMBER_PROFILE;
CREATE TABLE MEMBER_PROFILE(
    FILE_NO NUMBER PRIMARY KEY
    ,USER_NO NUMBER
    ,CHANGE_NAME VARCHAR2(512)
    ,CONSTRAINT MEMBER_PROFILE_FK FOREIGN KEY(USER_NO) REFERENCES MEMBER(USER_NO) ON DELETE CASCADE
);

DROP SEQUENCE MEMBER_PROFILE_SEQ;
CREATE SEQUENCE MEMBER_PROFILE_SEQ NOCACHE NOCYCLE;

SELECT * FROM MEMBER_PROFILE;




에러 처리

✨ControllerAdvice)

ErrorProcessor

@ControllerAdvice(annotations = Controller.class)
@Slf4j
public class ErrorProcessor {

	@ExceptionHandler(Exception.class)
	public String errorProcess(Exception e) {
		//서버도 예외를 알게하기
		log.error(e.toString());
		return "error/exception";
	}
}

log4j.xml

	<!-- FileAppender txt -->
	<appender name="fatxt" class="org.apache.log4j.FileAppender">
		<param name="file" value="D:/logForSpring/logs/myLogFile.txt" />
		<param name="append" value="true" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %-5p: %c - %m %n" />
		</layout>
	</appender>

...

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="fatxt" />
		<appender-ref ref="console" />
	</root>



web.xml

	<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/views/error/exception404.jsp</location>
	</error-page>



home.jsp

<body>

	<%@ include file="/WEB-INF/views/common/header.jsp" %>
	
	<div id="div-main">
		<h1>홈페이지</h1>
	</div>
</body>


common/header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/css/common/header.css">

	<div id="div-header">
		<table border="1">
			<tr>
				<td>빈칸</td>
				<td colspan="2"><img width="100%" height="50px" src="${pageContext.request.contextPath}/resources/imgs/qr.png">로고</td>
				<td>빈칸</td>
			</tr>
			<tr>
				<td>메뉴1</td>
				<td>메뉴2</td>
				<td>메뉴3</td>
				<td><a href="member/login">로그인</a></td>
			</tr>
		</table>
	</div>
  • ✨위아래 html, head, body.. 등 없애기


member/join.jsp

<body>

	<%@ include file="/WEB-INF/views/common/header.jsp" %>
	
	<div id="div-main">
		<h1>회원가입 페이지</h1>
		
		<form action = "" method = "post" enctype="multipart/form-data">
	        아이디 : <input type = "text" name = "userId"/><br>
	        비밀번호 : <input type = "password" name = "userPwd"/><br>
	        닉네임 : <input type = "text" name = "userNick"/><br>
	        나이 : <input type = "number" min="0" name = "userAge"/><br>
	        성별 : 
	        <select name="userGender">
	        	<option value="m">남자</option>
	        	<option value="f">여자</option>
	        </select><br>
	        사진 : <input type = "file" name = "f" accept=".jpg, .png"/><br>
	        <img id="profileImg">
	        <input type = "submit" value ="회원가입"/>
	    </form>
	</div>
	
	<script type="text/javascript">
		let fileTag = document.querySelector("input[name=f]");
		
		fileTag.onchange = function(){
			//파일 있는지 확인
			//console.log(fileTag.files.length);
			if(fileTag.files.length > 0){
				//미리보기 작업 실행
				let reader = new FileReader();
				reader.onload = function(data){
					console.log(data);
					let imgTag = document.querySelector("#profileImg");
					imgTag.src = data.target.result;
					/* imgTag.width = "200px";
					imgTag.height = "200px"; */
				}
				reader.readAsDataURL(fileTag.files[0]);
			}else{
				
			}
		}
	
	</script>

</body>



member/login.jsp

<body>

	<%@ include file="/WEB-INF/views/common/header.jsp" %>
	
	<div id="div-main">
		<h1>로그인 페이지</h1>
	
		<form action = "" method = "post">
	        아이디 : <input type = "text" name = "userId"/><br>
	        비밀번호 : <input type = "password" name = "userPwd"/><br>
	        <input type = "submit" value ="로그인"/>
	    </form>
		
		<a href="join">회원가입</a>
	</div>
</body>



✨✨css, assets 경로

  • src/main/resources/css 폴더, imgs 폴더 등...
#div-header{
	width: 80vw;
	height: 20vh;
	margin:0 auto;
}

#div-header table tr td{
    cursor:pointer;
}

#div-header table{
	width: 80%;
	height: 100%;
	text-align: center;
	margin:0 auto;
}

#div-header table tr:nth-child(1){
	height: 100px;
}
#div-header table tr:nth-child(2){
	height: 50px;
}

#div-main{
	width:80vw;
	margin: auto;
}

좋은 웹페이지 즐겨찾기