4

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 );

        }

    }
Squiggs.
  • 4,299
  • 6
  • 49
  • 89

1 Answers1

1

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

Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51