这些年写过的无厘头代码(四)Springboot 下在Controller中万金油解参

在写后台webapi时,接口总是需要定义一定的参数对象与前端请求进行呼应,然而在一些服务接口数量多,参数多,请求方式多的情况下,总是会出现获取不到前端请求参数数据。因此前后端之间交互的耦合又增高了。

前端发起微服务请求时,POST和GET、加上传输的数据类型json 、text,在Springboot里解析出来的方法五花八门,有的用RequestBody,有的又使用QueryString,用错了,参数就不知道传哪去了。其实,传输的参数都在Request对象中,都是一个一个键值对,因此,我就想着Controller所有服务接口就只统一传一个Request作为参数,将数据读取到一个静态Map<String,Object> 对象中,后面具体实现层在从这个变量中处理逻辑数据。

直接上代码:

///处理Request中的参数,并统一将key处理为小写,前端传递参数可忽略大小写了

public static Map<String, Object> getRequestParas(HttpServletRequest request) throws Exception {
        
		Map<String, Object> combineResultMap = new HashMap<String, Object>();//合并是处理既在URL里传参又在data对象中传参,最终统一返回
		// 创建参数队列
		Map<String, Object> resultParas = new HashMap<String, Object>();
		Map<String, Object> otherParams = new HashMap<String, Object>();
        
		if (request.getMethod().equalsIgnoreCase("POST")) {
            //POST下处理
			Enumeration<String> postNames = request.getParameterNames();
			while (postNames.hasMoreElements()) {
				String name = postNames.nextElement();
				String value = request.getParameter(name);
				resultParas.put(name.toLowerCase(), getDecodeValue(value));
			}
			combineResultMap.putAll(resultParas);
			//--------------在combineResultMap.putAll方法中会有后面覆盖相同key数据情况,POST传递以body中数据为准,
			// --------------所以解析body放后面
			String applicationJSONType = "application/json";
			String contentType = request.getContentType();
			if (StringUtils.isNull(contentType) == false && contentType.toLowerCase().contains(applicationJSONType)) {
				BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
				StringBuilder responseStrBuilder = new StringBuilder();
				String inputStr;
				while ((inputStr = streamReader.readLine()) != null) {
					responseStrBuilder.append(inputStr);
				}
				if (StringUtils.isNull(responseStrBuilder.toString()) == false) {
					otherParams = JSON.parseObject(responseStrBuilder.toString(), Map.class);
					combineResultMap.putAll(MapHelper.key2Lower(otherParams));
				}
			}
		} else {
            //GET 下处理
			String queryString = request.getQueryString();
			if (queryString != null) {
				String[] paras = queryString.split("&");
				for (String kv : paras) {
					int splitIndex = kv.indexOf('=');
					if (splitIndex != -1) {
						String name = kv.substring(0, splitIndex);
						String value = kv.substring(splitIndex + 1);
						resultParas.put(name.toLowerCase(), getDecodeValue(value));
					}
				}
			}
			combineResultMap.putAll(resultParas);
		}
		return combineResultMap;
	}

这个方法就将所有参数接收到Map<String,Object>对象中了,经过多次试验,满足前端各种类型的请求。

在RequestBody传参时,有个非常恶心的就是后端响应时,第一次可以读取参数数据,当逻辑中再次访问参数对象时,参数,没了!找了很多资料也没找到哪的问题,因此,我只能在初始化服务校验拦截类中抽取参数,放到全局静态变量中。

@Component("authInterceptor")
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        WebHelper.SetRequestParams(request);//读一遍参数;
}
  
public class WebHelper {

  public static Map<String, Object> RequestParams = null;//全局静态变量存储传参

  public static void SetRequestParams(HttpServletRequest request) throws Exception {
        RequestParams = SpringContextHelper.getRequestParas(request);
    }

}

经过上面整合,在应用时就方便多了。

Controller:

@Validated
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @Autowired
    private UserService sysUserService;

    @RequestMapping(value = "/get", method = {RequestMethod.GET, RequestMethod.POST})
    public Object query(HttpServletRequest request) {
        try {
            return sysUserService.QueryUser(request) ;
        } catch (Exception e) {
            throw new Exception("用户查询失败!" + e.getMessage(), e);
        }
    }

    @RequestMapping(value = "/details/get", method = {RequestMethod.GET, RequestMethod.POST})
    public Object queryDetail(HttpServletRequest request) throws Exception { 
        try {
           return  sysUserService.QueryUserDetail(request); 
        } catch (Exception e) {
            throw new Exception("用户查询失败!" + e.getMessage(), e);
        }
    }
}

Service :

@Service
public class UserService extends BaseService {

   public Object QueryUser(HttpServletRequest request) throws Exception {

        Map<String, Object> params = WebHelper.RequestParams;//从静态变量获取传参,
        //都是键值对,非常方便 
       
        String userid =StringHelper.handleNull(params.get("userid")) ;
        String sn = StringHelper.handleNull(params.get("sn")) ; 

        ...............
   }

...................

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的示例代码,供您参考: ```c #include "stm32f4xx_hal.h" #include "MPU6050.h" #include "inv_mpu_dmp_motion_driver.h" #define MPU6050_ADDR 0xD0 extern I2C_HandleTypeDef hi2c1; static void delay_ms(uint32_t ms) { HAL_Delay(ms); } uint8_t i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data) { HAL_StatusTypeDef status = HAL_OK; status = HAL_I2C_Mem_Write(&hi2c1, (uint16_t)slave_addr<<1, (uint16_t)reg_addr, 1, (uint8_t*)data, length, 1000); if(status == HAL_OK) return 0; return 1; } uint8_t i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data) { HAL_StatusTypeDef status = HAL_OK; status = HAL_I2C_Mem_Read(&hi2c1, (uint16_t)slave_addr<<1, (uint16_t)reg_addr, 1, data, length, 1000); if(status == HAL_OK) return 0; return 1; } void MPU6050_DMP_Init(void) { unsigned char dmp_memory[DMP_MEMORY_SIZE]; unsigned short dmp_features; int result; MPU6050_Initialize(); result = dmp_load_motion_driver_firmware(); if (result) return; dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)); dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL; result = dmp_enable_feature(dmp_features); if (result) return; result = dmp_set_fifo_rate(100); if (result) return; result = mpu_set_dmp_state(1); if (result) return; result = dmp_set_interrupt_mode(DMP_INT_CONTINUOUS); if (result) return; result = mpu_reset_fifo(); if (result) return; } void MPU6050_GetQuaternion(long *q) { unsigned char more; short sensors; unsigned char fifoCount; unsigned char fifoBuffer[1024]; int result; result = dmp_read_fifo(fifoBuffer, 1024, &sensors, &more, &fifoCount); if (result == 0 && fifoCount > 0) { dmp_get_quaternion(fifoBuffer, q); } } void MPU6050_GetRawAccel(short *data) { unsigned char more; short sensors; unsigned char fifoCount; unsigned char fifoBuffer[1024]; int result; result = dmp_read_fifo(fifoBuffer, 1024, &sensors, &more, &fifoCount); if (result == 0 && fifoCount > 0) { dmp_get_raw_accel(fifoBuffer, data); } } void MPU6050_GetCalibratedGyro(short *data) { unsigned char more; short sensors; unsigned char fifoCount; unsigned char fifoBuffer[1024]; int result; result = dmp_read_fifo(fifoBuffer, 1024, &sensors, &more, &fifoCount); if (result == 0 && fifoCount > 0) { dmp_get_calibrated_gyro(fifoBuffer, data); } } ``` 在这个示例代码,我们使用了STM32 HAL库来控制I2C接口,使用了MPU6050库来控制MPU6050芯片,使用了inv_mpu_dmp_motion_driver库来实现DMP功能。这个示例代码只是一个简单的实现,如果您需要更多的功能,可以参考相关库的文档来进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值