65일차 2023-06-09

2023. 6. 9. 19:26Spring Boot

Spring Boot

 

SessionAttrubuteController.java 아래 추가

3.AuthenticationCommand.java 생성

 

SessionAttributeController.java

1. 서블릿 API 사용하는 경우

 

2. 커맨드 객체 미 사용 시

Annotation.jsp

 

 

SessionAttributeController.java

Exception용

 

 

3. 커맨드 객체 사용 시

 

 

응답바디

 

※자바스크립트 전에 배웠던 것(HTML5 때)

form으로 보낼 때 get방식은 요청헤더에서 key=value로 가는 거고
post방식은 요청바디에 key=value로 전송하는 것
form은 무조건 key =value방식으로 보냄

 

Annotation.jsp에서 

아래 

 

(ex. 추가로 fetch로 해본 코드 예제)

<script>
	//※서버에 key = value형식이 아닌 json형식으로 데이타 보내기
	function json(){
		var data={id:$('#id').val(),pwd:$('#pwd').val()};
		console.log(data);
		console.log(JSON.stringify(data));
		//1.J
		//
		$.ajax({
			url:'<c:url value="/Annotaion/RequestBody.do"/>',
			method:'POST',
			data:JSON.stringify(data),
			contentType:"application/json",
			dataType:'json'
		}).done(data=>{
			console.log('서버에서 받은 데이타:',data);
			console.log('아이디:%s,비번:%s',data.id,data.pwd);
		}).fail(e=>{
			console.log('에러발생:',e);
		});
		//2. fetch 자바스크립트 함수 사용 - 모듈을 임포트할 필요 없다. 자바스크립트에서 제공하는 함수
		  //https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
		  /*fetch('<c:url value="/Annotation/RequestBody.do"/>',{method:'POST',headers: {
			    "Content-Type": "application/json",
		  },body:JSON.stringify(data)})
		  .then(function (response) {
		    console.log(response);
		    return response.json();		  
		  })
		  .then(function(data){
			  console.log(data);
			  console.log('아이디:%s,비번:%s',data.id,data.pwd);
		  })
		  .catch(function (error) {
		    console.log(error);
		  });*/
		  //3.axios 모듈 사용 - https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js모듈 임베딩 필요
		//https://axios-http.com/kr/docs/intro
		/*
		 axios.post('<c:url value="/Annotation/RequestBody.do"/>', data)
		  .then(function (response) {
		    //console.log(response);
		    console.log(response.data);
		    console.log('아이디:%s,비번:%s',response.data.id,response.data.pwd);
		  })
		  .catch(function (error) {
		    console.log(error);
		  });*/	
	}

</script>

 

 

 

ResponseBodyController.java

 

요청 바디

RequestBodyController.java

package com.kosmo.springapp.basic.annotation;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/*
	@RestController :주로 데이타만 보낼때(@Controller + @ResponseBody와 같다)
	@Controller : 주로 페이지를 보낼때
	@RequestBody : 클라이언트로부터 JSON형식의 데이타 받을 때 사용 .
				   스프링 부트는 내장되어 있다(Jackson라이브러리)
				   스프링 메이븐(레거시)는 내장되어 있지 않다
	Jackson라이브러리 : 자바 객체(DTO계열 혹은 컬렉션)를 JSON형식(자스 객체)으로
	                  JSON형식(자스 객체)을 자바객체로 변환시켜주는 라이브러리

	※
	- @RequestParam 혹은 커맨드 객체로 데이타 받기
		Form 및 A링크로 보내는 데이타(KEY=VALUE형태:id=KIM&pwd=1234) : 정상적으로 받는다
	  JSON형식의 데이타({KEY:VALUE}:{"id":"KIM","pwd":"1234"}) :
        @RequestParam받으면 400에러
        커맨드 객체로 받으면 세터가 호출이 안되서 커맨드객체의 속성이 null이다
	  
	- @RequestBody 커맨드 객체 혹은 맵으로 데이터 받기(단, 문자열로 받아도 되나 파싱해야 한다)
	   Form 및 A링크로 보내는 데이타 : 415에러:Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported)
	   JSON 형식데이타 : 정상적으로 받는다 
	   ※즉 JSON 형식데이타는  무조건 @RequestBody 사용하자.
*/
@Controller
public class RequestBodyController {
	/*1
	@RequestMapping("/Annotation/RequestBody.do")
	@ResponseBody
	//RequestParam으로 받을떄
	//form태그:정상
	//자바스크립트의 JSON형식의 테이타:
	//받지못한다.단,key=value형식은 잘 받는다
	public String requestParam(@RequestParam Map paramMap) throws JsonProcessingException {
		ObjectMapper mapper= new ObjectMapper();
		Map jmap = new HashMap();
		jmap.put("id",paramMap.get("id"));
		jmap.put("pwd",paramMap.get("pwd"));
		return mapper.writeValueAsString(jmap);
	}1*//////////////////
	
	/*2
	//RequestParam으로 받을떄
	//form태그:정상
	//자바스크립트의 JSON형식의 테이타:
	//받지못한다.단,key=value형식은 잘 받는다
	public String command(AuthenticationCommand auth) throws JsonProcessingException {
		System.out.println("아이디"+auth.getId());
		ObjectMapper mapper= new ObjectMapper();
		Map jmap = new HashMap();
		jmap.put("id",auth.getId());
		jmap.put("pwd",auth.getPwd());
		return mapper.writeValueAsString(jmap);
	}/////////////////
	2*/
	
	//RequestParam으로 받을떄
	//form태그:정상
	//자바스크립트의 JSON형식의 테이타:
	//받지못한다.단,key=value형식은 잘 받는다
	/*
	public String requestBody(@RequestBody AuthenticationCommand auth) throws JsonProcessingException {
		System.out.println("아이디"+auth.getId());
		ObjectMapper mapper= new ObjectMapper();
		Map jmap = new HashMap();
		jmap.put("id",auth.getId());
		jmap.put("pwd",auth.getPwd());
		return mapper.writeValueAsString(jmap);
	}*/////////////////
	/*
	public String requestBody(@RequestBody Map paramMap) throws JsonProcessingException {
		ObjectMapper mapper= new ObjectMapper();
		Map jmap = new HashMap();
		jmap.put("id",paramMap.get("id"));
		jmap.put("pwd",paramMap.get("pwd"));
		return mapper.writeValueAsString(jmap);
	}*/
	/*
	public AuthenticationCommand requestBody(@RequestBody AuthenticationCommand auth)  {
		return auth;
	}*/
	
	//String으로 변환할 필요 없이 바로 커맨드 객체나 맵 컬렉션을 반환하면 된다
	public Map requestBody(@RequestBody Map paramMap)  {
		return paramMap;
	}
	
	
}

 

 

Annotation.jsp

RequestHeaderController.java

 

 

 

결과)

 

 

속성 파일


-속성 파일에서 키=값의 형태로 정의해 두고 소스코드에서 주입받아 사용할 수 있다. (ex: server.port=8080)
-스프링부트 환경설정 파일인 application.properties는 디폴트 속성파일로
 자동 감지된다


 단, application.properties이 아닌 속성 파일은 자동 감지가 안 돼서

 PropertySourcesPlaceholderConfigurer 빈을 컨테이너에 등록하고

 @PropertySource어노테이션으로 해당 속성파일의 위치를 설정해야 한다.
 
-소스 코드에 주입은 @Value어노테이션으로 읽어서 주입한다

#application.properties
           spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
            spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe



#소스코드
         @Value("${spring.datasource.driver-class-name}")
         private String driverClassName;
         @Value("${spring.datasource.url}")
         private String url;
  

 

 

 

Index.jsp

IndexController.java

 

 

 

 

Properties.jsp

 

PropertiesController.java 컨트롤러

이걸 어디서 가져오는가?

application.properties

key=value로 가져옴

결과)

 

내가 만든 properties에서 읽어오기

 database.properties를 읽어오기

database.properties

 

읽기 위해서는 bean을 등록해야 된다

PlaceHolderConfig.java 생성

 

결과) NOT 디폴트 속성 파일

 

 

 

 

 

 

데이터 베이스

-커넥션 풀이란?

 

  • 웹 환경에서 처럼 데이터베이스와의 연결이 빈번하게 발생하는 경우,
    그때마다 커넥션을 생성하고 닫게 되면
    리소스의 낭비와 연결 시 시간소비를 하게 된다
    이를 개선하기 위해 미리 커넥션을 생성해 Pool에 넣어 놓고 요청이 
    있으면 커넥션을 Pool에서 가져다 쓰고
    다 쓰고 나면 다시 Pool에 반납한다. 이런 기법을 커넥션 풀이라 한다.

 

  • 스프링 부트는 기본적으로 데이터베이스 연결 시 커넥션 풀을 사용한다.
    즉 데이터베이스에 연결하기 위한 라이브러리(pom.xml에 의존성 추가)와 application.properties에 
    간단한 설정(스프링 부트 2.7.14는 에러)으로
    DBCP(DataBase Connection Pool)을 사용할 수 있다
    하지만 @Configuration과 @Bean어노테이션을 사용해 데이터 소스를 컨테이너에 빈으로 등록하는 것이 
    유리하다

    스프링부트 2.0 이전에는 Tomcat JDBC Connection Pool를 사용했으나
    스프링부트 2.0 이후에는 HikariCP를 디폴트로 사용한다

 

  • 히카리에 대해서 알아보기

https://github.com/brettwooldridge/HikariCP

 

GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

光 HikariCP・A solid, high-performance, JDBC connection pool at last. - GitHub - brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.

github.com

 

프로젝트 생성 시 Oracle Driver 미 선택 시

 

1) POM.XML 설정

 

		//오라클 접속용
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.4</version>
			<scope>runtime</scope>
		</dependency>
		//혹은(아래 넣어주기)
		<dependency>
			<groupId>com.oracle.database.jdbc</groupId>
			<artifactId>ojdbc8</artifactId>
			<scope>runtime</scope>
		</dependency>
		//히카리 커넥션풀용 넣어주기 원래2.0이상은 내장인데 없다면 넣어주기
		<dependency>
		   <groupId>com.zaxxer</groupId>
		   <artifactId>HikariCP</artifactId>		   
		</dependency>

 

2) 데이터베이스 연결

 

		//자바코드로 설정
		@Configuration
		public class DatabaseConfig {

	

			@Value("${driver-class-name}")
			private String driverClassName;
			@Value("${url}")
			private String url;
			@Value("${user}")
			private String username;
			@Value("${password}")
			private String password;
			
		
			@Bean 	
			public DataSource dataSource() {
				
				HikariConfig hikariConfig = new HikariConfig();
				hikariConfig.setDriverClassName(driverClassName);
				hikariConfig.setJdbcUrl(url);
				hikariConfig.setUsername(username);
				hikariConfig.setPassword(password);
				hikariConfig.setAutoCommit(true);
				hikariConfig.setConnectionTimeout(30000);
				hikariConfig.setMaximumPoolSize(10);
				return new HikariDataSource(hikariConfig);
			}
		}

 

3) 데이터 소스 주입받기

	@Autowired
	private DataSource dataSource;

 

연결 테스트용  테이블 생성 sql

Microsoft Windows [Version 10.0.19045.2965]
(c) Microsoft Corporation. All rights reserved.

C:\Users\kosmo>sqlplus system/kosmo1234

SQL*Plus: Release 11.2.0.2.0 Production on 금 6월 9 14:44:25 2023

Copyright (c) 1982, 2014, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> CREATE USER SPRING IDENTIFIED BY SPRING;

User created.

SQL> GRANT CONNECT,RESOURCE TO SPRING;

Grant succeeded.

SQL> COMMIT;

Commit complete.

SQL>

 

 

 

Index.jsp

IndexController.java

Database.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>   
<jsp:include page="/WEB-INF/views/template/Top.jsp"/>
    <div class="container" style="margin-top:50px">
        <div class="jumbotron bg-info">
            <h1>Spring Framework <small>Database</small></h1>          
        </div><!--jumbotron-->
        <fieldset class="form-group border p-3">
        	<legend class="w-auto px-3">데이타베이스 연결하기</legend>
        	<p><span class="text-danger font-weight-bolder">${message}</span> <span class="text-success">${param.method}</span></p>
    		<ul class="list-unstyled">
    			<li><a href="<c:url value="/Database/HikariConnectionPool.do?method=HIKARI_CONNECTION_POOL"/>">히카리 커넥션 풀  사용</a></li>
    		</ul>
        </fieldset>            
    </div><!--container-->
<jsp:include page="/WEB-INF/views/template/Footer.jsp"/>

 

환경설정하기

 

커넥트 풀로 연결

pom.xml

추가

 

 

DatabaseConfig.java

package com.kosmo.springapp.basic.database;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

@Configuration
public class DatabaseConfig {
	
	//데이타 베이스 연결정보
	@Value("${driver-class-name}")
	private String driver;
	@Value("${oracle-url}")
	private String url;
	@Value("${user}")
	private String user;
	@Value("${password}")
	private String password;
	
	@Bean
	public DataSource dataSource() {
		//HikariConfig객체 생성후 데이타베이스 연결 및 커넥션 풀 정보 설정
		HikariConfig hikariConfig = new HikariConfig();
		hikariConfig.setDriverClassName(driver);
		hikariConfig.setJdbcUrl(url);
		hikariConfig.setUsername(user);
		hikariConfig.setPassword(password);
		//히카리 커넥션 풀 관련 설정 추가
		//자동 커밋 설정(기본값 true) 
		hikariConfig.setAutoCommit(true);
		//IDLE상태에 있는 커넥션이 없을 때 즉 모든 커넥션이 사용 중일때
		//ConnectionTimeout이 지날 때까지 getConnection() 호출은 블록킹된다(기본값:30초)
		hikariConfig.setConnectionTimeout(30000);		
		//커넥션 풀에 최대 커넥션 수.(기본값: 10)
		hikariConfig.setMaximumPoolSize(10);
		//DataSource를 상속받은 HikariDataSource객체 반환
		//위의 HikariConfig객체로 설정후
		return new HikariDataSource(hikariConfig);
	}////////////////
}

 

DatabaseController.java

package com.kosmo.springapp.basic.database;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class DatabaseController {
	
	@Autowired
	private DataSource dataSource;
	
	@GetMapping("/Database/HikariConnectionPool.do")
	public String connectionPool(Model model) throws SQLException {
		
		//주입받은 DataSource객체로 Connection객체 얻기
		Connection conn= dataSource.getConnection();
		//데이타 저장
		model.addAttribute("message", conn==null?"[데이타베이스 연결실패]":"[데이타베이스 연결성공]");
		//커넥션 객체 풀에 반납
		if(conn !=null) conn.close();
		
		//뷰정보 반환
		return "database06/Database";
	}
}

결과)

 

 

유효성 검증  

  • -폼의 입력값을 검증한다
     즉 데이터의 값이 유효한지 조건에 맞는지 확인하는 것이다
         올바르지 않은 데이터를 서버로 전송되는 것을 막기 위함이다.

 

  • -유효성 검증과 관련된 주요 어노테이션
    @NotNull : Null 불가
    @Null : Null만 입력 가능
    @NotEmpty : Null 및 빈 문자열("") 불가
    @NotBlank : Null 및 빈 문자열 그리고 빈 공백 불가
    @Size(min=,max=) : 문자열 및 배열, 컬렉션등의 최소, 최대 크기 유효조건 지정
    @Pattern(regex=) : 정규 표현식으로 유효조건 지정
    @Max(숫자) : 지정한 숫자값 이하인지 체크
    @Min(숫자) :  지정한 숫자값 이상인지 체크
    @Future : 현재보다 이후 날짜인지 체크
    @Past : 현재보다 과거날짜 인지 체크
    @Positive : 양수만 입력가능
    @PositiveOrZero : 양수와 0만 입력가능
    @Negative : 음수만 입력가능
    @NegativeOrZero : 음수와 0만 입력가능
    @Email : 이메일 형식인지 체크
    @Digits(integer=, fraction = ) : 정수와 소수 자리 수 체크

1) POM.XML설정

 

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-validation</artifactId>
	</dependency>

 

2) DTO계열 클래스에 어노테이션으로 요효성 설정 ex)

		public class DTO계열 {
			
			@NotNull(message="필드1을 입력하세요")
			private String field1;
			
			@Size(min=2,message="최소 2개이상 선택해야 합니다")
			private String field2;
			
			@Size(min=4,max=8,message="최소 4자에서 8자 사이여야 합니다")
			private List<String> field3;
			
			@Email(message="이메일 형식이 아닙니다")
			private String field4;
			@Pattern(regexp="[0-9]{3}-[0-9]{4}-[0-9]{4}",message="전화번호 형식이 아닙니다")
			private String field5;
			
			@Digits(integer=3, fraction=0, message="숫자는 3자리여야 합니다")
			private String field6;
			
			//게터/세터
			...
		}

3)@Vaild 어노테이션으로 유효성 검사

		@PostMapping
		public String execute(@Valid DTO계열클래스 변수, Errors errors) {
			if(errors.hasErrors()) {
				return "폼뷰";
			}
			return "성공시 뷰";
		}
		@Valid에 의해 제출된 폼 데이타로 DTO계열 클래스의 유효성 검사를 수행
		검사 중 에러가 발생하면 에러의 상세 내역이 Errors 객체에 저장된다. 
		Errors객체의 hasErrors()라는 함수를 사용하여 에러가 있는지 확인.

4) JSP에서 에러메시지 출력

		<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

		<form:errors path="소문자자로시작하는 DTO클래스명.DTO의 속성명"/>으로 출력

 

 

유효성 검사

Index.jsp

IndexController.java

 

Validation.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="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<style>
	#name\.errors,#years\.errors,#inter\.errors,#grade\.errors,#gender\.errors{
		color:red;
		font-weight: bold;
	}
	
</style>
<jsp:include page="/WEB-INF/views/template/Top.jsp" />
<div class="container" style="margin-top: 50px">
	<div class="jumbotron bg-info">
		<h1>
			Spring Framework <small>Validation</small>
		</h1>
	</div>
	<!--jumbotron-->
	<fieldset class="form-group border p-3">
		<legend class="w-auto px-3">유효성 검증</legend>
		<form action="<c:url value="/Validation/Validation.do"/>"
			method="post">
			<div class="form-group">
				<label><kbd class="lead">이름</kbd></label> <input type="text"
					value="${param.name}" class="form-control" name="name"
					placeholder="이름를 입력하세요">
					<form:errors path="formCommand.name"/>
				<!-- 에러 메시지 표시 <접두어:errors path="커멘드객체명.속성명"/>단
				,커맨드 객체명은 소문자로 시작-->


			</div>
			<div class="form-group">
				<label><kbd class="lead">나이</kbd></label> <input type="text"
					value="${param.years}" class="form-control" name="years"
					placeholder="나이를 입력하세요">
					<form:errors path="formCommand.years"/>

			</div>
			<div class="form-group">
				<label><kbd class="lead">성별</kbd></label>
				<div class="d-flex">
					<div class="custom-control custom-radio mr-2">
						<input type="radio" class="custom-control-input" name="gender"
							<c:if test="${param.gender=='남자'}">checked</c:if> value="남자"
							id="male1"> <label for="male1"
							class="custom-control-label">남자</label>
					</div>
					<div class="custom-control custom-radio">
						<input type="radio" class="custom-control-input" name="gender"
							<c:if test="${param.gender=='여자'}">checked</c:if> value="여자"
							id="female1"> <label for="female1"
							class="custom-control-label">여자</label>
					</div>
					&nbsp;<form:errors path="formCommand.gender"/>	
					
				</div>
			</div>
			<div class="form-group">
				<label><kbd class="lead">관심사항</kbd></label>
				<div class="d-flex">
					<div class="custom-control custom-checkbox">
						<input type="checkbox" class="custom-control-input" name="inter"
							<c:if test="${fn:contains(fn:join(inter,','),'정')}">checked</c:if>
							value="정치" id="POL1"> <label class="custom-control-label"
							for="POL1">정치</label>
					</div>
					<div class="custom-control custom-checkbox mx-2">
						<input type="checkbox" class="custom-control-input" name="inter"
							<c:if test="${fn:contains(fn:join(inter,','),'경')}">checked</c:if>
							value="경제" id="ECO1"> <label class="custom-control-label"
							for="ECO1">경제</label>
					</div>
					<div class="custom-control custom-checkbox">
						<input type="checkbox" class="custom-control-input" name="inter"
							<c:if test="${fn:contains(fn:join(inter,','),'연')}">checked</c:if>
							value="연예" id="ENT1"> <label class="custom-control-label"
							for="ENT1">연예</label>
					</div>
					<div class="custom-control custom-checkbox ml-2">
						<input type="checkbox" class="custom-control-input" name="inter"
							<c:if test="${fn:contains(fn:join(inter,','),'스')}">checked</c:if>
							value="스포츠" id="SPO1"> <label
							class="custom-control-label" for="SPO1">스포츠</label>
					</div>
					&nbsp;<form:errors path="formCommand.inter"/>

				</div>
			</div>
			<div class="form-group">
				<label><kbd class="lead">학력사항</kbd></label> <select name="grade"
					class="custom-select mt-3 custom-select-lg">
					<option value="">학력을 선택하세요</option>
					<option value="초등학교"
						<c:if test="${param.grade=='초등학교'}">selected</c:if>>초등학교</option>
					<option value="중학교"
						<c:if test="${param.grade=='중학교'}">selected</c:if>>중학교</option>
					<option value="고등학교"
						<c:if test="${param.grade=='고등학교'}">selected</c:if>>고등학교</option>
					<option value="대학교"
						<c:if test="${param.grade=='대학교'}">selected</c:if>>대학교</option>
				</select>
				<form:errors path="formCommand.grade"/>
			</div>
			<button type="submit" class="btn btn-primary">확인</button>
		</form>
	</fieldset>
</div>
<!--container-->
<jsp:include page="/WEB-INF/views/template/Footer.jsp" />

 

Command객체 생성

FormCommand.java

package com.kosmo.springapp.basic.validation;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

public class FormCommand {
	//폼의 파라미터명과 같게 속성(멤버변수) 정의
	@NotBlank(message = "이름을 입력하세요")
	private String name;
	
	@NotBlank(message = "나이를 입력하세요")
	@Pattern(regexp = "[0-9]{1,3}",message = "나이는 숫자만...")
	private String years;
	
	@NotNull(message = "성별을 선택하세요")
	private String gender;
	
	@NotNull(message = "관심사항을 선택하세요")
	@Size(min = 2,message = "최소 2개이상 선택하세요")
	private String[] inter;
	
	@NotBlank(message = "학력을 선택하세요")
	private String grade;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getYears() {
		return years;
	}

	public void setYears(String years) {
		this.years = years;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String[] getInter() {
		return inter;
	}

	public void setInter(String[] inter) {
		this.inter = inter;
	}

	public String getGrade() {
		return grade;
	}

	public void setGrade(String grade) {
		this.grade = grade;
	}
}

 

서버 간에 유효성 검사를 한다 

ValidationController.java

package com.kosmo.springapp.basic.validation;

import java.util.Arrays;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class ValidationController {

	@PostMapping("/Validation/Validation.do")
	//매개변수 순서 : ※FormCommand다음에 Errors순으로
	public String validate(@Valid FormCommand form,Errors errors,Model model) {
		//FormCommand의 필드 중 어나 하나라도 유효성에 실패한다면 
		//Errors객체의 hasErrors()메소드는 true를 반환한다
		
		//체크박스는 무조건 여러개 선택하더라도 첫번째 것만 포워드 된다
		model.addAttribute("inter", form.getInter());
		
		if(errors.hasErrors()) {
			for(FieldError value: errors.getFieldErrors()) {
				System.out.println(value.getField()+" : "+value.getDefaultMessage());
			}
			//유효성 검증 실패시 다시 입력 폼으로 포워드
			return "validation07/Validation";
		}
		//유효성 검증 성공시 출력 페이지로 포워드
		return "validation07/ValidationResult";
	}
}

만약 유효성 검사를 통과했을 시

ValidationResult.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="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<jsp:include page="/WEB-INF/views/template/Top.jsp" />
<div class="container" style="margin-top: 50px">
	<div class="jumbotron bg-info">
		<h1>
			Spring Framework <small>Validation</small>
		</h1>
	</div>
	<!--jumbotron-->
	<fieldset class="form-group border p-3">
		<legend class="w-auto px-3">유효성 검증 완료</legend>
		<div class="form-group">
			<label><kbd class="lead">이름</kbd></label> <input type="text"
				value="${param.name}" class="form-control" name="name"
				placeholder="이름를 입력하세요">
			
		</div>
		<div class="form-group">
			<label><kbd class="lead">나이</kbd></label> <input type="text"
				value="${param.years}" class="form-control" name="years"
				placeholder="나이를 입력하세요">			
		</div>
		<div class="form-group">
			<label><kbd class="lead">성별</kbd></label>
			<div class="d-flex">
				<div class="custom-control custom-radio mr-2">
					<input type="radio" class="custom-control-input" name="gender"
						<c:if test="${param.gender=='남자'}">checked</c:if> value="남자"
						id="male1"> <label for="male1"
						class="custom-control-label">남자</label>
				</div>
				<div class="custom-control custom-radio">
					<input type="radio" class="custom-control-input" name="gender"
						<c:if test="${param.gender=='여자'}">checked</c:if> value="여자"
						id="female1"> <label for="female1"
						class="custom-control-label">여자</label>
				</div>				

			</div>
		</div>
		<div class="form-group">
			<label><kbd class="lead">관심사항</kbd></label>
			<div class="d-flex">
				<div class="custom-control custom-checkbox">
					<input type="checkbox" class="custom-control-input" name="inter"
						<c:if test="${fn:contains(fn:join(inter,','),'정')}">checked</c:if>
						value="정치" id="POL1"> <label class="custom-control-label"
						for="POL1">정치</label>
				</div>
				<div class="custom-control custom-checkbox mx-2">
					<input type="checkbox" class="custom-control-input" name="inter"
						<c:if test="${fn:contains(fn:join(inter,','),'경')}">checked</c:if>
						value="경제" id="ECO1"> <label class="custom-control-label"
						for="ECO1">경제</label>
				</div>
				<div class="custom-control custom-checkbox">
					<input type="checkbox" class="custom-control-input" name="inter"
						<c:if test="${fn:contains(fn:join(inter,','),'연')}">checked</c:if>
						value="연예" id="ENT1"> <label class="custom-control-label"
						for="ENT1">연예</label>
				</div>
				<div class="custom-control custom-checkbox ml-2">
					<input type="checkbox" class="custom-control-input" name="inter"
						<c:if test="${fn:contains(fn:join(inter,','),'스')}">checked</c:if>
						value="스포츠" id="SPO1"> <label class="custom-control-label"
						for="SPO1">스포츠</label>
				</div>
			
			</div>
		</div>
		<div class="form-group">
			<label><kbd class="lead">학력사항</kbd></label> <select name="grade"
				class="custom-select mt-3 custom-select-lg">				
				<option value="초등학교"
					<c:if test="${param.grade=='초등학교'}">selected</c:if>>초등학교</option>
				<option value="중학교"
					<c:if test="${param.grade=='중학교'}">selected</c:if>>중학교</option>
				<option value="고등학교"
					<c:if test="${param.grade=='고등학교'}">selected</c:if>>고등학교</option>
				<option value="대학교"
					<c:if test="${param.grade=='대학교'}">selected</c:if>>대학교</option>
			</select>
			
		</div>
		
	</fieldset>
</div>
<!--container-->
<jsp:include page="/WEB-INF/views/template/Footer.jsp" />

 

결과)

바로 페이지 이동을 했을때
체크용으로 아무것도 입력 없이 확인 눌렀을때
체크를 하나만 했을때 유효성 검사가 나타난다

 

Spring에서 콘솔)

 

param으로&nbsp; 값을 남김

 

ValidationResult.jsp로 넘어감

모든 유효성 검사를 통과했을 시

'Spring Boot' 카테고리의 다른 글

67일차 2023-06-13  (0) 2023.06.13
66일차 2023-06-12  (0) 2023.06.12
64일차 2023-06-08  (0) 2023.06.08
63일차 2023-06-07  (0) 2023.06.07
62일차 2023-06-05  (0) 2023.06.05