Serge Tahé
Serge Tahé

Reputation: 2089

How to change the posted values with a spring mvc interceptor

Does anyone know how to change the posted values with a spring mvc interceptor ? I have seen some examples but none about this subject. I know how to get them but i don't know how to modify them.

@Component
public class CultureInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {

    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        // we get the posted values
        String culture = request.getParameter("culture");
        String a = request.getParameter("a");
        String b = request.getParameter("b");
        System.out.println(String.format("[CultureInterceptor culture=%s, a=%s, b=%s]", culture, a, b));
        if (culture != null && a != null && b != null && "fr-FR".equals(culture)) {
            a = a.replace(",", ".");
            b = b.replace(",", ".");
        }
        System.out.println(String.format("[CultureInterceptor culture=%s, a=%s, b=%s]", culture, a, b));
        return true;
    }

Above, I have created a copy of posted values [a] and [b] but i haven't modified them in the request. Any idea to do that ?

Upvotes: 1

Views: 8603

Answers (3)

paul
paul

Reputation: 13471

If what you want is modify one modelAttribute that you render in the modelAndAttribute you can use his own annotation.

@ModelAttribute("here you put your entity name")
public Entity bindModel(final HttpServletRequest request) throws CandidacyException {
    String foo = request.getParameter("foo");
    foo = foo.concat("add new data");
    Entity entity = new Entity();
    entity.setFoo(foo);
    return entity;
}

Upvotes: 0

Serge Tahé
Serge Tahé

Reputation: 2089

I answer my own question. In fact it is rather complex and it took me some time to find a working solution. First, I created a filter in a Spring configuration class (Spring Boot environment exactly) :

@Configuration
@ComponentScan({ "istia.st.springmvc.config", "istia.st.springmvc.controllers", "istia.st.springmvc.models" })
@EnableAutoConfiguration
public class Config extends WebMvcConfigurerAdapter {
    @Bean
    public Filter cultureFilter() {
        return new CultureFilter();
    }

}

Here we declare a filter that will (by default) filter every request before it attains the final handler. Then I created the filter :

public class CultureFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // next handler 
        filterChain.doFilter(new CultureRequestWrapper(request), response);
    }
}

[OncePerRequestFilter] is a Spring class. The trick is to replace the actual request with a new one [CultureRequestWrapper(request)]. Then I created the CultureRequestWrapper :

public class CultureRequestWrapper extends HttpServletRequestWrapper {

    public CultureRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String[] getParameterValues(String name) {
        // posted values a et b
        if (name != null && (name.equals("a") || name.equals("b"))) {
            String[] values = super.getParameterValues(name);
            String[] newValues = values.clone();
            newValues[0] = newValues[0].replace(",", ".");
            return newValues;
        }
        // other cases
        return super.getParameterValues(name);
    }

}

I redefined the [getParameterValues] of [HttpServletRequest] but it depends on the final servlet that will manage the request. We have to redefine the [HttpServletRequest] methods used by this servlet.

Upvotes: 5

Master Slave
Master Slave

Reputation: 28569

You shouldn't be changing anything in the HttpServletRequest as it should represent the request as it came from the client. The construct that is used for scenarios such as yours, is HttpServletRequestWrapper.

What you should do is extend the HttpServletRequestWrapper, override the getParameter method where you can apply your param change logic, and forward your wrapped request further down the forwarding chain. This link can be of help to you, note that I don't think that this will work in an interceptor, and a filter is a right place to handle it, but you might try

Upvotes: 0

Related Questions