Spring

Spring의 요청/응답 처리 방법

J휘 2024. 10. 8. 16:15

@RequestMapping(" ") : 서블릿으로 요청이 들어오면 실행할 메소드를 매핑해줌

@ResponseBody : ajax요청에 대한 응답을 위한 Controller에 작성해주는 @로, 기본적인 세팅이 jsp응답으로 되어있기 때문에 반환값을 http응답 객체에 직접 작성하겠다라는 의미를 가지고 있다.

@Component : Bean에 Class를 등록시켜준다

@Controller : @Component의 기능에 Controller객체가 가질 수 있는 예외처리등이 추가된 @

@RestController : 데이터만 반환하는 비동기통신의 Controller에 작성하는 @

@Crosstroller : @Component + Controller객체가 가질 수 있는 예외처리등이 추가된 @

@Service : @Component보다 더 구체화해서 service객체에 알맞게 been에 등록 [Service]

@Repository : @Repository -> 데이터접근객체에 부여해주는 @Comoponent기능이 포함된 @ [Dao]

 


@Autowired

: 의존성주입을 사용할 때 사용하는 @

- 클래스 내에서 필요한 객체를 직접 생성하지 않고 spring컨테이너가 관리하는 객체(Bean)를 주입받아 사용할 수 있게 함

# 기존 객체 생성방식은 객체간의 결합도가 높다.(=소스코드 수정이 일어날 경우 하나하나 전부 다 바꿔줘야함)

# 서비스가 동시에 매우 많은 요청이 올 경우 그만큼의 객체가 생성된다.

이를 위한 게 바로 의존성 주입

 

# 의존성 주입 (DI = Dependency Injection)

> 코드 결합도가 낮아지고 코드를 분리할 수 있음

 

1) 필드 주입방식

> 스프링 컨테이너가 객체를 생성한 후, @Autowired가 붙은 필드에 의존성을 주입한다.

 

2) 생성자 주입방식

> 스프링 컨테이너가 객체를 생성할 때, @Autowired가 붙은 생성자를 통해서 필요한 의존성을 주입한다.

 

필드 주입방식의 문제점은 객체가 생성되고 나서 프레임워크가 의존성을 주입하기 때문에

그 사이 간격의 시간동안 의존성이(new~)가 생기지 않은 시점이 존재한다.

이에 반해 생성자 주입방식은 객체가 생성될 때 의존성이 주입되기 때문에 완전한 초기화 상태로 사용을 보장할 수 있고

이 때문에 테스트 기능성과 유지보수성이 좋아진다.


< Spring에서 클라이언트가 보낸 정보를 받는 방법 >

 

1. HttpServletRequest를 활용해서 전달값을 가져오기

  메소드에 매개변수로 HttpServletRequest를 작성해두면
  스프링컨테이너가 해당 메소드를 호출할 때 자동으로 객체생성해서 매개변수로 주입해준다.

	@RequestMapping("login.me")
	public String loginMember(HttpServletRequest request) {
		String id = request.getParameter("userId");
		String pwd = request.getParameter("userPwd");
		return null;
	}

2. @RequestParam 어노테이션을 이용하는 방법

 @RequestParam = request.getPrameter(키)로 벨류를 추출하는 역할을 대신해주는 어노테이션
 value속성의 값으로 jsp에서 작성했던 name속성값을 담으면 알아서 해당 매개변수로 받아올 수 있다.
 만약, 요청할때의 값이 비어있는 경우 defaultValue속성으로 기본값을 지정할 수 있다.
   
  # default와같은 설정을 사용하지않고 요청받은 key값과 매개변수명을 동일하게 해준다면
  @RequestParam 생략할 수 있다.

@RequestMapping("login.me")
public String loginMember(@RequestParam(value="userId", defaultValue="test222") String id, 
							String userPwd){ //매개변수명 동일
    System.out.println(id);
    System.out.println(userPwd);
    return "main";
}

 


3. 커맨드 객체 방식

  해당 메소드의 매개변수로
  요청시 전달값을 담고자하는 클래스 타입으로 만들어 준 뒤
  전달되는 key값과 매개변수 클래스의 필드명을 동일하게 작성해주면
  객체를 생성하여 값을 담아서 전달해준다.

public String loginMember(Member m) { //key값과 매개변수 클래스의 필드명 동일
	Member loginMember = memberService.loginMember(m);
	if (loginMember == null) {
		System.out.println("로그인 실패");
	} else {
		System.out.println("로그인 성공");
	}

< 요청처리 후에 응답데이터를 담고,

응답페이지로 포워딩 또는 url재요청 처리하는 방법 >

 

1. 스프링에서 제공하는 [Model객체]를 이용하는 방법

  >> 포워딩할 응답뷰로 전달하고자하는 데이터를 Map형식(k-v)으로 담을 수 있는 영역 

  # Map형식은 키값형태의 데이터를 저장하는 자료구조로 키는 중복이 안되지만 값은 중복이 가능해서 특정 키를 이용해서 값을 빠르게 조회가 가능하다는 장점이 있다.

Model객체는 requestScope   >>  요청할 동안만 살아있음

 request.setAttribute()  => model.addAttribute()   

@RequestMapping("login.me")
	public String loginMember(Member m, HttpSession session, Model model) { // Model객체 이용
		Member loginMember = memberService.loginMember(m);

		if (loginMember == null) {
			System.out.println("로그인 실패");
            
            	 	// request.setAttribute() 대신 model.addAttribute() 사용
			model.addAttribute("errorMsg", "로그인실패"); // requestScope에 에러문구를 담는다.
			return "/common/errorPage";
		} else {
			session.setAttribute("loginUser", loginMember);
			System.out.println("로그인 성공");
			return "redirect:/";
		}

2. 스프링에서 제공하는 [ModelAndView객체]를 이용 (데이터를 담고 리턴형식까지 지정할 수 있음)

 

@RequestMapping("login.me")
	public ModelAndView loginMember(Member m, HttpSession session, ModelAndView mv) {
		Member loginMember = memberService.loginMember(m);
        
		if (loginMember == null) {
			System.out.println("로그인 실패");
			//model.addAttribute("errorMsg", "로그인실패");
			mv.addObject("errorMsg", "로그인실패");
			mv.setViewName("common/errorPage"); //리턴형식 지정
		} else {
			session.setAttribute("loginUser", loginMember);
			System.out.println("로그인 성공");
			//return "redirect:/"; 원래의 방식
			mv.setViewName("redirect:/");
		}