開發中,app端給服務端會傳基礎參數、其他參數,一般基礎參數app端都會傳給服務端,其他參數則是根據不同接口傳不同參數。若以表單的形式提交的數據:
其中請求參數params就是上文所說的其他參數,而除了它都是基本參數,param的值是json字符串,對於這種請求方式用@RequestParam、@RequestBody都不能滿足要求,用spring中自定義的參數解析器恰好可以解決這個問題。
首先定義映射參數的類
UserParam:
public class UserParam extends BaseParam{ private UserInfoEntity params;//其他參數映射類 public UserInfoEntity getParams() { return params; } public void setParams(UserInfoEntity params) { this.params = params; } public void setParamsFromJson(String json){ UserInfoEntity userInfoEntity = null; try { userInfoEntity = JSONUtils.json2pojo(json,UserInfoEntity.class); } catch (Exception e) { e.printStackTrace(); } setParams(userInfoEntity); } }
BaseParam(基礎參數類):
public class BaseParam { public String token; public String channel; public String clientId; public String getToken() { return token; } public void setToken(String token) { this.token = token; } public String getChannel() { return channel; } public void setChannel(String channel) { this.channel = channel; } public String getClientId() { return clientId; } public void setClientId(String clientId) { this.clientId = clientId; } }
Controller類方法
@RestController public class HelloController { @Autowired UserInfoService userInfoService; @PostMapping(value = "/lios/boot/ok",produces = {"application/json;charset=utf-8"}) public Object ok(UserParam param){ return userInfoService.selectByMobile(param.getParams().getMobile()); } }
自定義參數解析器類
public class CustomArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { Class paramObjClass = methodParameter.getParameterType(); if(BaseParam.class.isAssignableFrom(paramObjClass)){ return true; //參數爲BaseParam.class類類型時,則執行resolveArgument方法 } return false; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Class paramObjClass = parameter.getParameterType();//獲取參數類類型 Object paramObj = paramObjClass.newInstance();//根據class new 出對象 Map<String, String[]> param = webRequest.getParameterMap();//獲取所有請求參數 for (Map.Entry<String, String[]> entry : param.entrySet()) { String[] val = entry.getValue(); if (val != null && "params".equals(entry.getKey())) { Method method = paramObjClass.getMethod("setParamsFromJson", String.class);//獲取到方法setParamsFromJson的對象 method.invoke(paramObj, val[0]);//把params的值當作形參傳入 } else if (val != null && val.length == 1) { //基礎類參數處理 Field field =null; if(paramObjClass.getName().equals(BaseParam.class.getName())){ field=paramObjClass.getDeclaredField(entry.getKey()); }else { field= paramObjClass.getSuperclass().getDeclaredField(entry.getKey()); } //把基礎參數的值放入UserParam中 if (field.getType().isAssignableFrom(String.class)) { field.set(paramObj, val[0]); } else if (field.getType().isAssignableFrom(Integer.class)) { field.set(paramObj, Integer.valueOf(val[0])); } else if (field.getType().isAssignableFrom(Long.class)) { field.set(paramObj, Long.valueOf(val[0])); } } } return paramObj; } }
配置
- 一般項目配置
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="com.lios.api.resolver.CustomArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven>
- springboot項目中配置
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @ImportResource({"classpath*:dispatcher-servlet.xml"}) public class LiosBootApplication extends WebMvcConfigurerAdapter { public static void main(String[] args) { SpringApplication.run(LiosBootApplication.class, args); } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { super.addArgumentResolvers(argumentResolvers); argumentResolvers.add(new CustomArgumentResolver()); } }