02월24(금) Spring MVC/EL

하이·2023년 2월 24일
0

수업

목록 보기
30/41
post-custom-banner

Spring Web Example
1. log4j
2. @controller
3. @RequsetMapping
4. InternalResourceView
5. model & modelandView
6. EL(Expression Language)

@Controller

특정 class가 "controller" 역할을 하는 Bean임을 나타내는 annotation

@RequestMapping(value="URL path")

(핸들러 어댑터에게 주는게 아무것도 없으면) handler에서 리턴이 안 되면, request URL을 이용해서 결과 Veiw Object를 생성하려고 함

controller

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

// 컨트롤러 지정
@Controller
public class TestController01 {
																//해당 클래스에 대한 정보를 인자로 넣음
	private static final Logger logger = LoggerFactory.getLogger(TestController01.class);

	// http://loaclhost:8080/springweb/여기부터~~
	// http://loaclhost:8080/springweb/testController01
	// value = "testController01" or "/testController01" 가능
	// 지정이 없으면 기본은 GET
	// testController01 얘가 view resolver로 가져감
	@RequestMapping(value="/testController01", method=RequestMethod.GET)
	String myMethod() {
		logger.debug("/springweb/testController01 호출 !!"); // 운영할 때 저 설정파일에 가서 debug가 출력 안 돼서 편함(???)
		return "sample01/testController01";
	}
}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>소리없는 아우성</h1>
</body>
</html>

testcontroller02

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestController02 {
	
	private static final Logger logger = LoggerFactory.getLogger(TestController01.class);
	
	@RequestMapping("/testController02/info")
	String myMethod01() {
		logger.debug("/testController02/info 호출 !!");
		
		return "sample01/testController02";
	}
	
	@RequestMapping("/testController02/profile")
	String myMethod02() {
		logger.debug("/testController02/profile 호출 !!");
		
		return "sample01/testController02";
	}
}

=
@RequestMapping을 클래스에 주면
하위 메소드들이 계층구조로!

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/testController02")
public class TestController02 {
	
	private static final Logger logger = LoggerFactory.getLogger(TestController01.class);
	
	@RequestMapping("/info")
	String myMethod01() {
		logger.debug("/testController02/info 호출 !!");
		
		return "sample01/testController02";
	}
	
	@RequestMapping("/profile")
	String myMethod02() {
		logger.debug("/testController02/profile 호출 !!");
		
		return "sample01/testController02";
	}
    
   	// 여러개의 핸들러를 하나의 URL에서 처리할 수 있음
	@RequestMapping(value= {"","/test01", "test02", "test03/*"})
	String myMethod03() {
		logger.debug("/testController02/멀티 호출 !!");
		
		return "sample01/testController02";
	}
}

testcon03

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

// client request method에 따른 handler 호출
// method=RequestMethod.GET


@Controller
@RequestMapping(value="/testController03")
public class TestController03 {
	
	private static final Logger logger = LoggerFactory.getLogger(TestController03.class);
	
	@RequestMapping(value="", method=RequestMethod.GET)
	String myMethod1() {
		return null;
	}
	
	
	@RequestMapping(value="", method=RequestMethod.POST)
	String myMethod2() {
		return null;
	}
}

03은 결과확인 안 했음

04

05

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value="/testController05")
public class TestController05 {
	
	private static final Logger logger = LoggerFactory.getLogger(TestController05.class);
	
	// GetMapping이 RequestMapping을 상속하고 있음
	@GetMapping(params="myName")
	String myMethod01() {
		logger.debug("testController05 호출 ---- myName");
		return "sample01/testController05";
	}
	
	// myMethod02가 myMethod01보다 자세해서 myMethod02를 찾아서 호출함
	// but 이렇게 쓰면 안 됨 !
	@GetMapping(params="myName=신사임당")
	String myMethod02() {
		logger.debug("testController05 호출 ---- myName=신사임당");
		return "sample01/testController05";
	}
}


06

package my.spring.springweb.sample01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceView;

@Controller
@RequestMapping(value="testController06")
public class TestController06 {

	private static final Logger logger = LoggerFactory.getLogger(TestController06.class);
	
	// 이거 진자로 Bean이 생성 되는 건가요?
	public TestController06() {
		logger.debug("TestController06 Bean 생성");
	}
	
	@GetMapping
	public ModelAndView showStaticView() {
		
		logger.debug("testController06 호출");
		
		// html인 경우 webapp하단부터 절대경로를 이용하면 편함
		InternalResourceView view = new InternalResourceView("/resources/sample01/testController06.html");
		
		// model 객체, view객체 두개를 가짐
		ModelAndView mav = new ModelAndView(view);
		
		return mav;
	}
}



07


EL(Expression Language)

: JSP 2.0 spec안에 포함되어 있음
: JSP(expression) <%= %> 대신 EL 사용함
: JSP Scriptlet <% %> - JSTL
=> 이 둘은 유지보수가 너무 힘들어서 EL과 JSTL을 사용함

EL로 data를 찾아서 찍어야함
${ 변수명(key값) }

변수명 찾는 방법
pageScope > requestScope > sessionScope > applicationScope 순서대로 찾음

  • pageScope는 pageContext객체가 포함되어 있음
  • requestScope는 request객체, Model객체
  • sessionScope는 session객체
  • applicationScope는 servletContext객체(공용객체)

-> 같은 이름의 변수가 다른 scope에 있을 수 있음

EL은 찾은 Scope를 명시할 수 있음
${sessionScope.myName}

EL의 표현법, 연산, 내장객체에 대해서 알아보자
① pageScope
② requestScope
③ sessionScope
④ applicationScope
=>1~4번은 해당 scope를 access할 때 사용하는 내장객체

⑤ param
: client request parameter의 이름과 값을 가지고 있는
⑥ header
: client request의 header 정보

  1. cookie

08

package my.spring.springweb.sample01;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import my.spring.springweb.sample01.vo.User;

@Controller
@RequestMapping(value="testController08")
public class TestController08 {

	private static final Logger logger = LoggerFactory.getLogger(TestController08.class);
	
	@PostMapping("useEL")
	public String myMethod(Model model) {
		model.addAttribute("myName", "홍길동");
		model.addAttribute("myAge", 20);
		
		List<String> list = new ArrayList<String>();
		list.add("강감찬");
		list.add("신사임당");
		
		model.addAttribute("myList", list);
		
		User user = new User("이순신",40);
		model.addAttribute("myUser", user);
		
		return "sample01/testController08";
	}
	
	
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>EL에 대해 알아보자</h1>
							<!-- requestMapping -->
	<form action="/springweb/testController08/useEL" method="post" >
		이름: <input type="text" name="userName"><br>
		나이: <input type="number" name="userAge">
		<br><br>
		<input type="submit" value="서버로 전송">
	</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>testController08.jsp 호출</h1>
	
	<h3>EL을 이용해서 데이터를 추출하는 다양한 방법</h3>
	<ul>
		<li>문자열 출력 -1 : ${ "test" }</li>
		<li>문자열 출력 -2 : ${ 'test' }</li>
		<br>
		<li>숫자 출력 : ${ 123123 }</li>
		<li>논리값 출력 : ${ true }</li>
		<li>null 출력 : ${ null }</li> <!-- null은 아예 출력 안 됨 -->
		<li>list 출력(myList[1]) : ${ myList[1] }</li>
		<br>
		<li>JavaBean(VO) : ${ myUser.userName }</li>
		<li>Map : ${ myName }</li>
		<br>
		<li>param객체를 써보자 : ${ param.userName }</li>
		<li>header객체를 써보자 : ${ header.referer }</li> <!-- referer은 뒤로가기 버튼에 쓰면 좋음 -->
		<br>
		<li>산술연산(+,-,*,/,%) : ${ param.userAge + 20 }</li>
		<li>논리연산(&&, ||, !) : ${ !false }</li>
		<li>비교연산(==, !=, 비교연산자사용가능) : ${ param.userAge < 20 }</li>
		<li>삼항연산( 논리값 ? a : b ) : ${ param.userAge < 20 ? "미성년자" : "성인"}</li>
		<br>
		<li>empty 연산 : ${empty ""} - ("")true</li>
		<li>empty 연산 : ${empty "abc"} - ("abc")false</li>
		<li>empty 연산 : ${empty null} - (null)true</li>
		<li>empty 연산 : ${empty null} - (null)true</li>
		<li>empty 연산 : ${empty myList} - (안에 2개 있음)false</li>
		
		
	</ul>
	<br><br>
	<a href="${ header.referer}">뒤로가기</a>
</body>
</html>



client request parameter
request.getParameter("myName");
이 방법 말고 다른 방식에 대해서 알아보자
ModelAndView class


sample02 - calc

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>연산할 두개의 숫자를 입력하고 연산자를 선택하세요!</h1>
	<br><br>
	<form action="/springweb/calc.do" method="post">
		<input type="number" name="firstNum" required="required">
		<select name="operator">
			<option value="plus"> + </option>
			<option value="minus"> - </option>
			<option value="mul"> * </option>
			<option value="div"> / </option>
		</select>
		<input type="number" name="secondNum" required="required">
		<br><br>
		<input type="submit" value="계산하기">
	</form>
</body>
</html>

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>연산성공!</h1>
	<!-- EL 검색순서
		 pageScope > requestScope > sessionScope > applicationScope 
	-->
	<%-- <% pageContext.setAttribute("myData", "소리없는 아우성!"); %> --%>
	<% pageContext.setAttribute("msg", "소리없는 아우성!"); %>
	<br>
	<h3>request.getAttribute("msg") - 결과는 : <%= request.getAttribute("msg") %></h3>
	<h3>$ { msg } - 결과는 : ${ msg } </h3>
	<h3>$ { param.msg } - 결과는 : ${ param.msg } </h3>
	<h3>$ { param.firstNum } - 결과는 : ${ param.firstNum } </h3>
	<h3>$ { pageScope.msg } - 결과는 : ${ pageScope.msg } </h3>
<%-- 	<h3>$ { pageScope.myData } - 결과는 : ${ pageScope.myData } </h3> --%>
	
	<a href="${ header.referer }">뒤로가기</a>
</body>
</html>
package my.spring.springweb.sample02;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import my.spring.springweb.sample01.TestController08;

@Controller
@RequestMapping("/calc.do")
public class CalcController {
	
	private static final Logger logger = LoggerFactory.getLogger(TestController08.class);
	
	@PostMapping				
	public ModelAndView process(@RequestParam("firstNum") int num1, int secondNum, String operator ) {
								// 넘어오는 키값이 html의 parameter값과 같으면 이렇게 씀.
								// 원래는 @RequestParam("firstNum") int firstNum => int firstNum
		
		// 사용자가 보내준 데이터를 받아야함
		// 이전에는, String num1 = request.getParameter("firstNum");
		// @RequestParam("")를 이용해서 받음 ! (String포함해서 primitive type인 경우)
		ModelAndView mav = new ModelAndView();
		String viewName = " ";
		
		if(operator.equals("div")&& secondNum == 0) {
			// 나눗셈을 하는데 분모가 0 => 무한대.. 무한대 개녕이 없음.. Exception
			viewName = "sample02/errorResult";
			mav.addObject("msg", "나눗셈은 0으로 나눌 수 없음!");
		} else {
			int result =0;
			if(operator.equals("plus")) {
				result = num1 + secondNum;
			} else if(operator.equals("minus")) {
				result = num1 - secondNum;
			} else if(operator.equals("mul")) {
				result = num1 - secondNum;
			} else {
				result = num1 / secondNum;
			}
			viewName = "sample02/calcResult";
			mav.addObject("msg",result);
		}
		
		mav.setViewName(viewName);	
		return mav;
	}
	
}



업로드중..


lombok

https://www.projectlombok.org/
다운로드 후 sts 재실행

pom.xml - project lombok dependency 추가
https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.26

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.26</version>
    <scope>provided</scope>
</dependency>
package my.spring.springweb.sample02.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
// @Data : 위의 5개를 모두 포함
@Data
public class User { 

	private String userName;
	private int    userAge;
	private String userDept;
	private String userAddress;
}
profile
기록의 즐거움 😆💻
post-custom-banner

0개의 댓글