[Spring] @RequestParam

Jeiniยท2023๋…„ 5์›” 20์ผ
0

๐Ÿƒย  Spring

๋ชฉ๋ก ๋ณด๊ธฐ
4/33
post-thumbnail

๐Ÿ’ก @RequestParam


โœ”๏ธ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•  ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ถ™์ด๋Š” ์• ๋„ˆํ…Œ์ด์…˜

โœ๏ธ @RequestParam: required=false & String year

@RequestMapping("/requestParam2")
//public String main2(@RequestParam(name="year", required=false) String year)
public String main2(String year) {
//		http://localhost/ch2/requestParam2         ---->> year=null
//		http://localhost/ch2/requestParam2?year    ---->> year=""
     System.out.printf("[%s]year=[%s]%n", new Date(), year);
     return "yoil";
}

โžก๏ธ public String main2(@RequestParam(name="year", required=false) String year)
: ์ƒ๋žต๋œ ๊ฒƒ. year๋ฅผ ํ•„์ˆ˜๋กœ ์ž…๋ ฅ์•ˆํ•ด๋„ ๋จ

  • required: ํ•„์ˆ˜์ž…๋ ฅ ์—ฌ๋ถ€
  • @RequestParam ์„ ๋ถ™์ด๋ฉด required๋Š” true๊ฐ€ ๋จ

โœ๏ธ @RequestParam: required=true & String year

   @RequestMapping("/requestParam3")
//  public String main3(@RequestParam(name="year", required=true) String year) {   // ์•„๋ž˜์™€ ๋™์ผ
    public String main3(@RequestParam String year) {
        System.out.printf("[%s]year=[%s]%n", new Date(), year);
        return "yoil";
    }
  • http://localhost/ch2/requestParam3?year
    โžก๏ธ year = ""

  • http://localhost/ch2/requestParam3
    โžก๏ธ 400 Bad Request.
    : required=true๋ผ์„œ ํด๋ผ์ด์–ธํŠธ ์ž˜๋ชป. ๋ฌด์กฐ๊ฑด year์˜ ๊ฐ’์„ ๋„ฃ์–ด์ค˜์•ผ ํ•จ


โœ๏ธ @RequestParam: required=false & int year

โœ”๏ธ defaultValue: ํ•„์ˆ˜์ž…๋ ฅ์ด ์—†๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.

@RequestMapping("/requestParam8")
public String main8(@RequestParam(required = false, defaultValue = "2021") int year) { 
     System.out.printf("[%s]year=[%s]%n", new Date(), year);
     return "yoil";
}
  • ํ•„์ˆ˜๊ฐ’ ์•„๋‹˜. ๊ทธ๋ž˜์„œ ์„œ๋ฒ„ ์˜ค๋ฅ˜ ํ•„์ˆ˜๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ฐ’์ด ์•ˆ ๋“ค์–ด์™”์„ ๋•Œ์˜ ๋Œ€๋น„๊ฐ€ ๋˜์–ด์žˆ์–ด์•ผ ํ•œ๋‹ค.

  • http://localhost/ch2/requestParam8
    โžก๏ธ 500 java.lang.IllegalStateException : Optional int parameter 'year' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
    : ํ•„์ˆ˜์ž…๋ ฅ์ด ์•„๋‹˜ โžก๏ธ ์„œ๋ฒ„ ์ž˜๋ชป
    : year ์ž์ฒด๊ฐ€ ์—†์–ด์„œ null ์ด ๋‚˜์˜ค๊ณ  ์ด null ๊ฐ’์€ int ๋กœ ๋ณ€ํ™˜ โŒ

  • http://localhost/ch2/requestParam8?year
    โžก๏ธ 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
    : ๋นˆ๋ฌธ์ž์—ด ์ˆซ์ž ๋ณ€ํ™˜ โŒ โžก๏ธ ํด๋ผ์ด์–ธํŠธ ์ž˜๋ชป

  • String ์œผ๋กœ ๋ฐ”๋กœ ๋ฐ›๋Š” ๊ฒƒ์ด ์•„๋‹Œ int ๋กœ ๋ณ€ํ™˜๋˜๋Š” ๊ฑฐ๋ผ์„œ ์—๋Ÿฌ๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ


โœ๏ธ @RequestParam: required=true & int year

โœ”๏ธ ํ•„์ˆ˜์ž…๋ ฅ์ผ ๋•Œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ค€๋‹ค.

@RequestMapping("/requestParam9")
    public String main9(@RequestParam(required = true) int year) {
        System.out.printf("[%s]year=[%s]%n", new Date(), year);
        return "yoil";
    }
  • http://localhost/ch2/requestParam9
    โžก๏ธ 400 Bad Request, Required int parameter 'year' is not present
    : ํ•„์ˆ˜์ž…๋ ฅ์ธ๋ฐ ์•ˆ์คฌ์œผ๋‹ˆ๊นŒ ํด๋ผ์ด์–ธํŠธ ์ž˜๋ชป

  • http://localhost/ch2/requestParam9?year
    โžก๏ธ 400 Bad Request, nested exception is java.lang.NumberFormatException : For input string: ""
    : ๋นˆ๋ฌธ์ž์—ด ์ˆซ์ž ๋ณ€ํ™˜ โŒ โžก๏ธ ํด๋ผ์ด์–ธํŠธ ์ž˜๋ชป

  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์ž…๋ ฅ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

โœ๏ธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

โœ๏ธ YoilTellerMVC.java

package kr.ac.jipark09.ch2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// ๋…„,์›”,์ผ์„ ์ž…๋ ฅํ•˜๋ฉด ์š”์ผ์„ ์•Œ๋ ค์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ
@Controller
public class YoilTellerMVC {
	@RequestMapping("/getYoilMVC")
    // required = true ํ•ด์คŒ
	public String main(
			@RequestParam(required = true) int year, 
			@RequestParam(required = true) int month,
			@RequestParam(required = true) int day,
			Model model
			) throws IOException {
		
		//1. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
		if(!isVaild(year, month, day)) {
			return "yoilError";
		}
		
		// 2. ์š”์ผ ๊ณ„์‚ฐ
		char yoil = getYoil(year, month, day);
		getYoil(year, month, day);
		
		// 3. ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ model์— ์ €์žฅ
		model.addAttribute("year", year);
		model.addAttribute("month", month);
		model.addAttribute("day", day);
		model.addAttribute("yoil", yoil);
		
		return "yoil"; // yoil.jsp๋ฅผ ๋ณด์—ฌ์ค˜๋ผ
	}

	private boolean isVaild(int year, int month, int day) {
		return true;
	}

	private char getYoil(int year, int month, int day) {
		Calendar cal = Calendar.getInstance();
		cal.set(year, month - 1, day);
		
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		return " ์ผ์›”ํ™”์ˆ˜๋ชฉ๊ธˆํ† ".charAt(dayOfWeek);
	}
}

  • day๋ฅผ ๋„ฃ์ง€ ์•Š์•„์„œ 400๋ฒˆ ์—๋Ÿฌ๊ฐ€ ๋‚˜์™”๋‹ค.
  • ์ด๋Ÿฐ ํ™”๋ฉด์ด ๋‚˜์˜ค๊ฒŒ ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ค€๋‹ค.

โœ๏ธ catcher ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ ๋งŒ๋“ฌ

โœ”๏ธ @ExceptionHandler๋ฅผ ๋ถ™์ด๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

@ExceptionHandler(Exception.class)
public String catcher(Exception e) {
	e.printStackTrace();
	return "yoilError";
}


year, month, day๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์ด๊ฒƒ๋“ค์„ ํ•˜๋‚˜๋กœ ํ•ฉ์นœ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด๋ณด์ž.

โœ๏ธ Date ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ „๋‹ฌ

โœ๏ธ YoilTellerMVC4.java

package kr.ac.jipark09.ch2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

// year, month, day๋ฅผ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ๋ด„ => ๊ฐ์ฒด๋กœ ๋งŒ๋“ค๊ธฐ(dto)
@Controller
public class YoilTellerMVC4 {
	@ExceptionHandler(Exception.class)
	public String catcher(Exception e) {
		e.printStackTrace();
		return "yoilError";
	}
	
	@RequestMapping("/getYoilMVC4")
	public String main(MyDate date, Model model) throws IOException {
		
		//1. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
		if(!isVaild(date)) {
			return "yoilError";
		}
		
		// 2. ์š”์ผ ๊ณ„์‚ฐ
		char yoil = getYoil(date);
		
		// 3. ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ model์— ์ €์žฅ
		model.addAttribute("date", date);
		model.addAttribute("yoil", yoil);
		
		return "yoil"; // yoil.jsp๋ฅผ ๋ณด์—ฌ์ค˜๋ผ
	}

	private boolean isVaild(MyDate date) {
		return isVaild(date.getYear(), date.getMonth(), date.getDay());
	}
	private boolean isVaild(int year, int month, int day) {
		if(year == 1 || month == 1 || day == 1) {
			return false;
		}
		return (1 <= month && month <= 12) && (1 <= day && day <= 31);
	}

	private char getYoil(MyDate date) {
		int year = date.getYear();
		int month = date.getMonth();
		int day = date.getDay();
		Calendar cal = Calendar.getInstance();
		cal.set(year, month - 1, day);
		
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		return " ์ผ์›”ํ™”์ˆ˜๋ชฉ๊ธˆํ† ".charAt(dayOfWeek);
	}

}

โœ๏ธ yoil.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>year=<%=request.getParameter("year") %></h1>
<!-- EL -->
<p>${myDate.year }๋…„ ${myDate.month }์›” ${myDate.day }์ผ์€ ${yoil }์ž…๋‹ˆ๋‹ค.</p>
</body>
</html>

โ“ ์ž…๋ ฅ๋˜๋Š” ๊ฐ’์ด year, month, day์ธ๋ฐ MyDate๋กœ ์ž˜ ๋‚˜์˜ค๋Š” ์ด์œ ๊ฐ€ ๋ญ˜๊นŒ?

์ด๋Ÿฌํ•œ ๋ถ€๋ถ„๋„ ์Šคํ”„๋ง์ด ์•Œ์•„์„œ ์ฐพ์•„๊ฐ€์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์˜ˆ์ œ๋ฅผ ๋ณด๋ฉฐ ์‚ดํŽด๋ณด์ž.

โœ๏ธ SetterCall

package com.fastcampus.ch2;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.springframework.util.StringUtils;

public class SetterCall {
	public static void main(String[] args) throws Exception{
		Map<String, String> map = new HashMap<>();
		map.put("year", "2021");
		map.put("month", "10");
		map.put("day", "1");
		
		Class<?> type = Class.forName("com.fastcampus.ch2.MyDate");

		// MyDate์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , map์˜ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. 
		Object obj = dataBind(map, type);
		System.out.println("obj="+obj); // obj=[year=2021, month=10, day=1]
	} // main

	private static Object dataBind(Map<String, String> map, Class<?> clazz) throws Exception {
		// 1. MyDate์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
//		Object obj = clazz.newInstance(); // deprecated method
		Object obj = clazz.getDeclaredConstructor().newInstance(new Object[0]);

		// 2. MyDate์ธ์Šคํ„ด์Šค์˜ setter๋ฅผ ํ˜ธ์ถœํ•ด์„œ, map์˜ ๊ฐ’์œผ๋กœ MyDate๋ฅผ ์ดˆ๊ธฐํ™”
		// 	 2-1. MyDate์˜ ๋ชจ๋“  iv๋ฅผ ๋Œ๋ฉด์„œ map์— ์žˆ๋Š”์ง€ ์ฐพ๋Š”๋‹ค.
		// 	 2-2. ์ฐพ์œผ๋ฉด, ์ฐพ์€ ๊ฐ’์„ setter๋กœ ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.
		Field[] ivArr = clazz.getDeclaredFields();
		
		for(int i=0;i<ivArr.length;i++) {
			String name = ivArr[i].getName();
			Class<?>  type = ivArr[i].getType();
			
			// map์— ๊ฐ™์€ ์ด๋ฆ„์˜ key๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ€์ ธ์™€์„œ setterํ˜ธ์ถœ 
			Object value = map.get(name); // ๋ชป์ฐพ์œผ๋ฉด value์˜ ๊ฐ’์€ null
			Method method = null;
			
			try {   // map์— iv์™€ ์ผ์น˜ํ•˜๋Š” ํ‚ค๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ, setter๋ฅผ ํ˜ธ์ถœ
				if(value==null) continue;
				
				method = clazz.getDeclaredMethod(getSetterName(name), type); // setter์˜ ์ •๋ณด ์–ป๊ธฐ	
				System.out.println("method="+method);
				method.invoke(obj, convertTo(value, type)); // obj์˜ setter๋ฅผ ํ˜ธ์ถœ
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		System.out.println(Arrays.toString(ivArr));
		
		return obj;
	}

	private static Object convertTo(Object value, Class<?> type) {
		// value์˜ ํƒ€์ž…๊ณผ type์˜ ํƒ€์ž…์ด ๊ฐ™์œผ๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
		if(value==null || type==null || type.isInstance(value))
			return value;
		
		// value์˜ ํƒ€์ž…๊ณผ type์ด ๋‹ค๋ฅด๋ฉด, ๋ณ€ํ™˜ํ•ด์„œ ๋ฐ˜ํ™˜
		if(String.class.isInstance(value) && type==int.class) // String -> int
			return Integer.valueOf(""+value);

		return value;
	}

	// iv์˜ ์ด๋ฆ„์œผ๋กœ setter์˜ ์ด๋ฆ„์„ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ("day" -> "setDay")
	private static String getSetterName(String name) {
//		return "set"+name.substring(0,1).toUpperCase()+name.substring(1);
		return "set" + StringUtils.capitalize(name); // org.springframework.util.StringUtils
	}
}
[์‹คํ–‰๊ฒฐ๊ณผ]
method=public void com.fastcampus.ch2.MyDate.setYear(int)
method=public void com.fastcampus.ch2.MyDate.setMonth(int)
method=public void com.fastcampus.ch2.MyDate.setDay(int)
[private int com.fastcampus.ch2.MyDate.year, private int com.fastcampus.ch2.MyDate.month, private int com.fastcampus.ch2.MyDate.day]
obj=[year=2021, month=10, day=1]
  1. ์š”์ฒญํ•œ ๊ฐ’๋“ค์ด HashMap์œผ๋กœ ๋‹ด๊ธด๋‹ค.

  2. MyDate ๋ผ๋Š” ํƒ€์ž…์ด ์žˆ์„ ๋•Œ bind() ๋ฉ”์„œ๋“œ๊ฐ€ Mapํ•˜๊ณ  ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.

    1) ํƒ€์ž…์œผ๋กœ ๋„˜์–ด์˜จ ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค.

    2) MyDate ์ธ์Šคํ„ด์Šค์˜ setter๋ฅผ ํ˜ธ์ถœํ•ด์„œ, Map์˜ ๊ฐ’์œผ๋กœ MyDate๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

    2-1. myDate์˜ ๋ชจ๋“  iv(์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜)๋ฅผ ๋Œ๋ฉด์„œ Map์— ์กด์žฌํ•˜๋Š”์ง€ ์ฐพ๋Š”๋‹ค.

    2-2. ์ฐพ์œผ๋ฉด, ์ฐพ์€ ๊ฐ’์„ setter๋กœ ๊ฐ์ฒด์— ์ €์žฅํ•œ๋‹ค.

    โžก๏ธ setter๊ฐ€ ์—†์œผ๋ฉด ์Šคํ”„๋ง์ด ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ์ง€ ๋ชปํ•จ. setter ํ•„์ˆ˜!


Reference
: https://fastcampus.co.kr/dev_academy_nks

profile
Fill in my own colorful colors๐ŸŽจ

0๊ฐœ์˜ ๋Œ“๊ธ€