2016-04-19 46 views
0

我有一個複雜的豆持有其餘的參數,例如:如何將HttpServletRequest參數添加到複雜的RestController bean?

public class MyRestParams { 
    private HttpServletRequest req; 
    private @NotBlank String name; 

    //getter, setter 
} 

用法:

@RestController 
@RequestMapping("/xml") 
public class MyServlet { 
    @RequestMapping(value = "/") 
    public void getTest(@Valid MyRestParams p) { 
     Sysout(p.getName()); //works when invoked with /xml?name=test 
     Sysout(p.getReq()); //always null 
    } 
} 

問題:HttpServletRequest總是空。是不是可以在bean本身中添加此參數?

回答

1

可以爲HandlerMethodArgumentResolver提供一個實現解決您MyRestParams

public class MyRestParamsArgumentResolver implements HandlerMethodArgumentResolver { 
    @Override 
    public boolean supportsParameter(MethodParameter parameter) { 
     return parameter.getParameterType().equals(MyRestParams.class); 
    } 

    @Override 
    public Object resolveArgument(MethodParameter parameter, 
            ModelAndViewContainer mavContainer, 
            NativeWebRequest webRequest, 
            WebDataBinderFactory binderFactory) throws Exception { 
     MyRestParams restParam = new MyRestParams(); 
     restParam.setReq((HttpServletRequest) webRequest.getNativeRequest()); 

     return restParam; 
    } 
} 

然後在它註冊您的WebMvcConfigurerAdapter

@EnableWebMvc 
@Configuration 
public class WebConfig extends WebMvcConfigurerAdapter { 
    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 
     argumentResolvers.add(new MyRestParamsArgumentResolver()); 
    } 
} 
+1

這是一個非常整潔的解決方案! – membersound

+1

您還需要確保Spring仍將在您的實現中綁定請求參數。否則,你得到你的HttpServletRequest,但其他bean屬性仍然是空的 –

-1

使用方法簽名春的這種形式將使用您的bean作爲一個模型屬性。 Spring將使用WebDataBinder(例如ServletRequestDataBinder)將您的請求參數綁定到匹配名稱的bean屬性。

由於沒有與您的bean屬性req匹配的請求參數,所以該字段將永遠不會被設置。即使請求中存在名稱爲req的參數,它也不會被轉換爲HttpServletRequest。

要收到實際的請求類型爲HttpServletRequest的參數添加到您的處理方法

@RequestMapping(value = "/") 
public void getTest(@Valid MyRestParams p , HttpServletRequest request) { 
    Sysout(p.getName()); //works when invoked with /xml?name=test 
    Sysout(request); //always null 
} 

或類型的參數WebRequest的,如果你不想自己綁到了Servlet API。

+0

你的答案說「這是不可能的」,但顯然它不是真的:http://stackoverflow.com/a/36722594/1240557 – kryger

+0

我沒有說它不可能。我解釋了爲什麼使用標準Spring實現該字段不會被設置。除此之外,爲什麼你必須讓你的設計複雜化才能讓HttpServletRequest設置爲POJO,這樣你就可以更容易。你是否注意到,在建議的實現中,你失去了數據綁定,你必須實現自己。當你可以做到乾淨簡單時,爲什麼會變得複雜 –