I'm currently trying to modify, (via a Spring filter) some of the request variables being posted into a form.
Reason being, I would like to implement better phone number validation, and better control how telephone numbers are formatted. For that part of the puzzle, I intend to use Google's Lib phone number in my model so like so:
private PhoneNumber mobileNumber;
One getter, with no mention of the prefix at all, given that the filter will hopefully do the hard work for me.
I initially thought that perhaps I could use an attribute converter to do this i.e.
@Convert(converter = PhoneNumberConverter.class )
private PhoneNumber mobileNumber;
However, there is a problem with that, in that if the field is a composite type, the JPA doesn't support it: https://github.com/javaee/jpa-spec/issues/105 (compositie because PREFIX is needed as well as NUMBER) to build a lib phone object.
So. A filter (or Interceptor?) is what I'm left with. My question is, I'm new to the Spring framework and I'm not 100% sure whether just modifying the raw request will allow instantiation of the PhoneNumber object in the model - (I presume not), but any guidance on how Spring manages to do its magic tying up of request variables into an object (by mapping getters and setters) and how I would go about doing this manually in the filter would be helpful. Is there any way of access this Model object in the filter so I can set it directly?
public class PhonePrefixFilter extends OncePerRequestFilter
{
@Override
protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain )
throws ServletException, IOException
{
String prefix = request.getParameter( "phonePrefix" );
if( StringUtils.isNotEmpty( prefix ) )
request.setAttribute( "mobileNumber", prefix + request.getAttribute( "mobileNumber" ) );
filterChain.doFilter( request, response );
}
}
AFAIK you cannot modify your request parameter directly. You need a HttpServletRequestWrapper
to provide custom getter to your parameter:
public static class PhoneRequestWrapper extends HttpServletRequestWrapper {
public PhoneRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
if (!("mobileNumber").equals(name)) {
return super.getParameter(name);
}
String prefix = getParameter("phonePrefix");
String mobileNumber = getRequest().getParameter("mobileNumber");
if (StringUtils.isNotEmpty(prefix) && StringUtils.isNotEmpty(mobileNumber)) {
return prefix + getRequest().getParameter("mobileNumber");
} else {
return mobileNumber;
}
}
}
Then create your filter:
public static class PhoneNumberFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws
ServletException,
IOException {
filterChain.doFilter(new PhoneRequestWrapper((HttpServletRequest) request), response);
}
@Override
public void destroy() {
}
}
And register it in your @Configuration
class:
@Bean
public Filter filterRegistrationBean() {
return new PhoneNumberFilter();
}
From now on, your request.getParamter("mobileNumber")
will have the value appended with phonePrefix
Since your question is not very clear, if you want to override the behaviour of @RequestParam
to get your phone number string, you can use custom HandlerMethodArgumentResolver
to resolve your parameter