์ค๋์ ์คํ๋ง mvc ์์ ์ ๊ณตํ๋ ArgumentResolver๋ฅผ ์ง์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช ํ๋ ค๊ณ ํฉ๋๋ค.
์ปจํธ๋กค๋ฌ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ Model, ServletRequest ๋ฑ๋ฑ ์ ์๋ง ํ๋ฉด ์ฝ๊ฒ ๊ฐ์ ธ๋ค ์ธ ์ ์๋ ์ด์ ๋ ์ด ArgumentResolver ๋๋ถ์ธ๋ฐ์, ์ปค์คํ ํ๊ฒ ๋ง๋ค์ด์ ์์ฃผ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค.
์๋ฃ๋ฅผ ์ฐพ๋ค ๋ณด๋ ์ด๋ ธํ ์ด์ ์ ๋ถ์ด๋ ๊ฒฝ์ฐ๋ ์๊ณ ์๋ถ์ด๊ธฐ๋ ํ๋๋ฐ
์ ์๊ฐ์ String, Integer ๋ฑ ๋ฒ์ฉ์ ์ธ ํด๋์ค๊ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๋ ์๋ณ์ ์ํด ์ด๋ ธํ ์ด์ ์ ๋ถ์ด๊ณ
ํด๋์ค๊ฐ ๋ช ํํ๊ฒ ๊ตฌ๋ถ๋๋ค๋ฉด ์ด๋ ธํ ์ด์ ์ ๋ถ์ด๋ ๊ฒ์ ๋ถํ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์์ ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ๋ช๊ฐ์ง ์ถ๊ฐ ์์กด์ฑ์ ์ถ๊ฐํ์ต๋๋ค.
// build.gradle
// apache lang3์ user-agent-parser๋ฅผ ํจ๊ป ์ถ๊ฐํ์ต๋๋ค.
plugins {
id 'org.springframework.boot' version '2.2.6.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.larry.blog'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
// https://mvnrepository.com/artifact/com.github.ua-parser/uap-java
compile group: 'com.github.ua-parser', name: 'uap-java', version: '1.4.3'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
}
test {
useJUnitPlatform()
}
Ip๋ฅผ ํ์ฑํ๋ ๊ธฐ๋ฅ๊ณผ User-Agent ์ ๋ณด๋ฅผ ํ์ฑํ ์ ๋ณด ๋ ๊ฐ์ง๋ฅผ ๊ฐ๊ฐ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ์๋์ ๊ฐ์ด ๋ ๊ฐ์ ArgumentResolver๋ฅผ ๋ง๋ค์์ต๋๋ค.
public class ClientArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(Client.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Parser parser = new Parser();
return parser.parse(webRequest.getHeader("User-Agent"));
}
}
public class ParsedIpArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(ParsedIp.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
String ipAddress = request.getHeader("X-Forwarded-For");
return StringUtils.defaultString(ipAddress,
parameter.getParameterAnnotation(ParsedIp.class).defaultValue());
}
}
๋ณดํต ์น์๋ฒ๋ฅผ ํ๋ก์๋ก ์ด์ฉํ๋ ๊ฒฝ์ฐ X-Forwarded-For๋ก Ip๋ฅผ ๊ฐ์ ธ์ค๋ฏ๋ก (์๋ ๊ฒฝ์ฐ๋ ๋ง์ต๋๋ค! IP๋ฅผ ํ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์๋ ์ถ๊ฐ ํฌ์คํ ํ๊ฒ ์ต๋๋ค.^^)
ํค๋๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋ง์ฝ ์๋ค๋ฉด ๊ธฐ๋ณธ ๊ฐ์ ์ฃผ๋๋ก ๋ง๋ค์์ต๋๋ค.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ParsedIp {
String defaultValue() default "UNKNOWN";
}
์คํ๋ง MVC Configuration ์ ๋ฑ๋กํด ์ค๋๋ค.
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(new ParsedIpArgumentResolver());
argumentResolvers.add(new ClientArgumentResolver());
}
}
์ฌ๊ธฐ๊น์ง ํ๋ค๋ฉด ์ฌ์ฉํ๋ ์ผ๋ง ๋จ์์ต๋๋ค!
@RestController
@Slf4j
public class MyController {
@GetMapping
public ResponseEntity<Void> ipTest(@ParsedIp(defaultValue = "Hello ip") String ip,
Client client) {
log.info("ip address: {}", ip);
log.info("client: {}", client.toString());
return ResponseEntity.ok().build();
}
}
์ปจํธ๋กค๋ฌ ๋ฉ์๋์ ์์ ๊ฐ์ด ํ์ํ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ํ์ ์ผ๋ก ๋ฑ๋กํ์ฌ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๊ฐ๋จํ ํ ์คํธ๋ฅผ ์ํด ์์ฒญ์ ํด๋ณด๋ฉด (๋๋ฐ์ด์ค๋ ์์ดํจ๋๋ก ํ์ต๋๋ค.)
ํ์ฑ๋ ๊ฒฐ๊ณผ๋ฌผ์ ํ์ธํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ํด์ ๊ฐ์์ ํ๋ก์ ํธ์ ์ ์ฉํ๊ฒ ์ ์ฉํ์๊ธธ ๋ฐ๋๋๋ค~๐๐
'ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์คํ๋ง] ์คํ๋ง์ ์ดํดํ๊ธฐ ์ด๋ ค์ด ์ด์ . ๋ค์ค ์ธํฐํ์ด์ค ์์ (0) | 2020.04.16 |
---|---|
http ํค๋๋ฅผ ์์ ํ๊ฒ ์ค์ ํ๋ ๋ฐฉ๋ฒ (0) | 2020.04.15 |
์ต๊ทผ๋๊ธ