원리는 간단하면서도 살짝 복잡합니다. 일단 HttpServletRequest 라는 개체는 setParameter 라는 것이 존재하지 않습니다. 이와 같이 매개변수를 개발자가 마음대로 조작할 수 있을 경우 문제가 더 클 수 있기 때문입니다. 그래서 약간의 우회적인 방법이 필요합니다.
먼저, Filter 을 등록해야 합니다. Interceptor 는 불가능한 것으로 압니다. Filter 에서 doFilter method 등을 Override 받아 구현할 때 HttpServletRequest, HttpServletResponse, FilterChain 을 매개변수를 받을 것입니다. 이 때 매개변수로 받은 HttpServletRequest 개체를 생성자로 받아서 이를 확장할 HttpServletRequestWrapper 클래스를 상속받아 구현하는 것입니다. 통상적으로 request 의 getParameterMap() 을 이용해 Map 에 매개변수들을 저장한 뒤 getParameter(), getParameterMap(), getParameterNames(), getParameterValues() 등을 Override 해서 구현하고, setParameter() 을 새롭게 구현(setParameter() 는 2 개의 오버로드된 method 로 구현합니다)하는 형태가 됩니다.
이렇게 구현된 HttpServletRequestWrapper 는 HttpServletRequest 의 구현체 중 하나이기 때문에 Controller 로 전송되어도 사용에 크게 문제가 없습니다(OOP Design Pattern 의 장점).
저는 보통 이렇게 구현해놓고 씁니다.
public class HttpRequestWithModifiableParameters extends HttpServletRequestWrapper {
Map<String, String[]> params;
public HttpRequestWithModifiableParameters(HttpServletRequest request) {
super(request);
this.params = request.getParameterMap();
}
@Override
public String getParameter(String name) {
String[] paramArray = getParameterValues(name);
if (paramArray != null && paramArray.length > 0) {
return paramArray[0];
} else {
return null;
}
}
@Override
public Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(params);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(params.keySet());
}
@Override
public String[] getParameterValues(String name) {
String[] result = null;
String[] temp = params.get(name);
if (temp != null) {
result = new String[temp.length];
System.arraycopy(temp, 0, result, 0, temp.length);
}
return result;
}
public void setParameter(String name, String value) {
String[] oneParam = {value};
setParameter(name, oneParam);
}
public void setParameter(String name, String[] values) {
params.put(name, values);
}
}
그래도 남용은 하지 말아야겠습니다.
잘배우고갑니다.
답글삭제잘배우고갑니다.
답글삭제