如何使用spring mvc拦截器更改发布的值

时间:2014-12-16 12:28:15

标签: spring spring-mvc interceptor

有谁知道如何使用spring mvc拦截器更改发布值?我看过一些例子但没有关于这个问题。我知道如何获得它们,但我不知道如何修改它们。

@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;
    }

上面,我创建了发布值[a]和[b]的副本,但我没有在请求中修改它们。有没有想过呢?

3 个答案:

答案 0 :(得分:5)

我回答我自己的问题。实际上它相当复杂,我花了一些时间才找到一个有效的解决方案。 首先,我在Spring配置类(Spring Boot环境)中创建了一个过滤器:

@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();
    }

}

这里我们声明一个过滤器,它将(默认情况下)在每个请求到达最终处理程序之前对其进行过滤。然后我创建了过滤器:

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]是一个Spring类。诀窍是用新的[CultureRequestWrapper(request)]替换实际的请求。然后我创建了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);
    }

}

我重新定义了[HttpServletRequest]的[getParameterValues],但它依赖于将管理请求的最终servlet。我们必须重新定义 这个servlet使用的[HttpServletRequest]方法。

答案 1 :(得分:0)

您不应该更改HttpServletRequest中的任何内容,因为它应该代表来自客户端的请求。用于诸如你的场景的构造是HttpServletRequestWrapper

您应该做的是扩展HttpServletRequestWrapper,覆盖 getParameter 方法,您可以在其中应用您的参数更改逻辑,并在转发链中进一步转发您的包装请求。 这个link对您有所帮助,请注意,我不认为这会在拦截器中起作用,并且过滤器是处理它的正确位置,但您可以尝试

答案 2 :(得分:0)

如果你想要的是修改你在modelAndAttribute中渲染的一个modelAttribute,你可以使用他自己的注释。

@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;
}