HandlerMethodArgumentResolver μ‚¬μš©

· β˜• 2 min read · πŸ‘€... views

이전에 νšŒμ‚¬μ—μ„œ λ‹€λ₯Έ ν”„λ‘œμ νŠΈ μ†ŒμŠ€λ₯Ό 보닀가 http ν—€λ”μ—μ„œ 보낸 정보λ₯Ό controller λ‹¨μ—μ„œ λ°”λ‘œ vo 둜 λ§€ν•‘ν•΄μ£ΌλŠ” μ½”λ“œλ₯Ό λ°œκ²¬ν–ˆλ‹€.
λ‹Ήμ‹œμ— 이거 κ½€ μœ μš©ν•˜κ²Œ μ“Έ 수 μžˆκ² λ„€. ν•˜κ³  μ§€λ‚˜κ°€κΈ°λ§Œ ν–ˆμ—ˆλŠ”λ°, μ΄λ²ˆμ— κΈ°νšŒκ°€ 생겼닀.

λͺ©ν‘œ

  • ν΄λΌμ΄μ–ΈνŠΈμ˜ IP λ₯Ό 컨트둀러 λ‹¨μ—μ„œ λ°”λ‘œ λ°›μ•„μ„œ μ²˜λ¦¬ν•˜κ³ μž 함.

1. ClientInfo 생성

1
2
3
4
5
6
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ClientInfo {
   private String clientIp;
}
  • 바인딩될 객체λ₯Ό 생성

2. ClientResolver μ–΄λ…Έν…Œμ΄μ…˜ 생성

1
2
3
4
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClientResolver {
}

3. ClientHandlerMethodArgumentResolver 생성

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class ClientHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(final MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(ClientInfo.class);
    }

    @Override
    public Object resolveArgument(final MethodParameter methodParameter,
                                  final ModelAndViewContainer modelAndViewContainer,
                                  final NativeWebRequest nativeWebRequest,
                                  final WebDataBinderFactory webDataBinderFactory) throws Exception {

        ClientInfo clientInfo = new ClientInfo(clientIp(nativeWebRequest));

        return clientInfo;
    }

    private String clientIp(final NativeWebRequest request) {
        String clientIp = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(clientIp) || "unknown".equalsIgnoreCase(clientIp)) {
     
            clientIp = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(clientIp) || "unknown".equalsIgnoreCase(clientIp)) {
     
            clientIp = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(clientIp) || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isEmpty(clientIp) || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isEmpty(clientIp) || "unknown".equalsIgnoreCase(clientIp)) {
            HttpServletRequest nativeRequest = (HttpServletRequest) request.getNativeRequest();
            clientIp = nativeRequest.getRemoteAddr();
        }
        return clientIp;
    }
}
  • supportsParameter λŠ” ν˜„μž¬ νŒŒλΌλ―Έν„°λ₯Ό resolver이 μ§€μ›ν•˜λŠ”μ§€μ— λŒ€ν•œ boolean
  • resolveArgument λŠ” 바인딩할 객체

4. resolver 등둝

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Configuration
public class WebMvcCustomConfiguration extends WebMvcConfigurerAdapter {

	...
	
    @Override
	public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> argumentResolvers) {
		argumentResolvers.add(new ClientHandlerMethodArgumentResolver());
	}
}
  • μŠ€ν”„λ§4.x λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ–΄μ„œ WebMvcConfigurerAdapter λ₯Ό 상속받아 μ‚¬μš©ν•œ 것 κ°™μ§€λ§Œ,
    spring boot μ—μ„œλŠ” WebMvcConfigurer 을 κ΅¬ν˜„ν•΄μ£Όλ©΄ λ˜λŠ” 것 κ°™λ‹€.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private ClientHandlerMethodArgumentResolver clientHandlerMethodArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(clientHandlerMethodArgumentResolver);
    }
}

5. Controller 생성

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Controller
public class IntroCreationController {

    private final IntroCreationService introCreationService;

    @Autowired
    public IntroCreationController(IntroCreationService introCreationService) {
        this.introCreationService = introCreationService;
    }

    @RequestMapping(value = "/api/save/intro", method = RequestMethod.POST)
    public ApiResponse createIntro(@RequestBody IntroCreationRequest request, @ClientResolver ClientInfo clientInfo) {
        ApiResponse apiResponse;
        try {
            AdminIntroData intro = introCreationService.createIntro(request, clientInfo);
            apiResponse = ApiResponse.success(intro);
        } catch (Exception e) {
            apiResponse = ApiResponse.fail(e.getMessage());
        }
        return apiResponse;
    }
}
  • 컨트둀러 λ§€μ†Œλ“œμ˜ νŒŒλΌλ―Έν„°μ— μ»€μŠ€ν…€ μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄ λœλ‹€.
Share on

snack
WRITTEN BY
snack
Web Programmer


What's on this Page