我正在與第三方供應商 API 集成。
我有一個 SpringBoot 和 Jackson 設定
他們向我發送了一個 POST 請求,該請求的型別為 formUrlEncoded 并且引數為 snake_case(總共超過 10 個引數,沒有正文)
例如
POST www.example.com?player_id=somePlayerId&product_id=someProductId&total_amount=totalAmount...
JSON 有許多開箱即用的幫助程式,但我找不到 formUrlEncoded 的任何幫助程式(我希望我遺漏了一些明顯的內容)。
我嘗試過@ModelAttribute和@RequestParam但沒有運氣。
我試圖避免@RequestParam MultiValueMap<String, String> params 自定義映射器選項
uj5u.com熱心網友回復:
@RequestParam 是最簡單的方法,它允許您定義查詢引數的確切名稱,例如:
@PostMapping
public String foo(@RequestParam("player_id") String playerId){
}
如果要將所有查詢引數系結到一個物件,則必須使用@ModelAttribute. 它基于DataBinder杰克遜,與杰克遜無關。默認情況下,它僅支持將查詢引數系結到欄位與查詢引數同名的物件。因此,您可以考慮將查詢引數系結到以下物件:
public class Request {
private String player_id;
private String product_id;
private Long total_amount;
}
如果您真的想從具有蛇形大小寫值的查詢引數系結到遵循傳統 Java 命名約定(即小駝峰式大小寫)的物件,則必須 cusomtize WebDataBinder。
這個想法是覆寫它addBindValues()并檢查查詢引數名稱是否為蛇形格式,將其轉換為小駝峰格式并將其添加為請求的系結值。就像是 :
public class MyServletRequestDataBinder extends ExtendedServletRequestDataBinder {
private static Converter<String, String> snakeCaseToLowerCamelConverter = CaseFormat.LOWER_UNDERSCORE
.converterTo(CaseFormat.LOWER_CAMEL);
public MyServletRequestDataBinder(Object target) {
super(target);
}
public MyServletRequestDataBinder(Object target, String objectName) {
super(target, objectName);
}
@Override
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
super.addBindValues(mpvs, request);
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames != null && paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
if(paramName.contains("_")) {
String[] values = request.getParameterValues(paramName);
if (values == null || values.length == 0) {
// Do nothing, no values found at all.
} else if (values.length > 1) {
mpvs.addPropertyValue(snakeCaseToLowerCamelConverter.convert(paramName), values);
} else {
mpvs.addPropertyValue(snakeCaseToLowerCamelConverter.convert(paramName), values[0]);
}
}
}
}
}
PS我正在使用番石榴幫助我將蛇形字母轉換為小駝峰字母。
但是為了使用定制的WebDataBinder,你必須反過來定制WebDataBinderFactory, RequestMappingHandlerAdapter因為:
- 定制
WebDataBinderFactory以創建定制的WebDataBinder - 自定義
RequestMappingHandlerAdapter以創建WebDataBinderFactory
就像是:
public class MyServletRequestDataBinderFactory extends ServletRequestDataBinderFactory {
public MyServletRequestDataBinderFactory(List<InvocableHandlerMethod> binderMethods,
WebBindingInitializer initializer) {
super(binderMethods, initializer);
}
@Override
protected ServletRequestDataBinder createBinderInstance(Object target, String objectName,
NativeWebRequest request) throws Exception {
return new MyServletRequestDataBinder(target, objectName);
}
}
和
public class MyRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
@Override
protected InitBinderDataBinderFactory createDataBinderFactory(List<InvocableHandlerMethod> binderMethods)
throws Exception {
return new MyServletRequestDataBinderFactory(binderMethods, getWebBindingInitializer());
}
}
最后注冊以使用RequestMappingHandlerAdapter您的配置中的定制:
@Configuration
public class Config extends DelegatingWebMvcConfiguration {
@Override
protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
return new MyRequestMappingHandlerAdapter();
}
}
uj5u.com熱心網友回復:
我不認為你缺少任何東西。查看RequestParamMethodArgumentResolver#resolveName 源,我看不到自定義請求引數匹配方式的方法。所以看起來你要么必須實作自己的決議器,要么只用注釋每個引數@RequestParam并提供名稱,例如@RequestParam("product_id") String productId
編輯:
至于ModelAttribute,ModelAttributeMethodProcessor使用WebDataBinder。同樣,您可以使用您的自定義來自定義它,DataBinder但我沒有發現任何開箱即用的支持別名的內容,就像 Jackson 所做的那樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/345449.html
標籤:弹簧靴 弹簧 mvc x-www-form-urlencoded
