文章目录
1、控制台
2024-11-06 14:45:40.557 ERROR 9560 --- [io-8087-exec-10] c.p.common.exception.ExceptionHandle : 缺少请求参数
org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'code' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:202)
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:113)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:166)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
2、ExceptionHandle
package com.productQualification.common.exception;
import com.productQualification.common.entity.BaseResult;
import feign.FeignException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NestedRuntimeException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
/**
* 统一异常处理
*/
@ControllerAdvice
@ResponseBody
public class ExceptionHandle {
private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
/**
* 未登录异常拦截
*/
@ExceptionHandler(value = ServletRequestBindingException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResult handle(ServletRequestBindingException e) {
logger.error("用户登录状态失效", e);
return BaseResult.failure(BaseResult.NOLOGIN, "未登录");
}
/**
* 参数验证异常拦截
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
public BaseResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
logger.error("缺少请求参数", e);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, "缺少请求参数");
}
/**
* 参数验证异常拦截
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
public BaseResult handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
logger.error("参数解析失败", e);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, "参数解析失败");
}
/**
* 参数验证异常拦截
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public BaseResult handleServiceException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
ConstraintViolation<?> violation = violations.iterator().next();
String message = violation.getMessage();
logger.error("参数验证失败 : {}", message, e);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, "参数验证失败 : " + message);
}
/**
* 参数验证异常拦截
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ValidationException.class)
public BaseResult handleValidationException(ValidationException e) {
logger.error("参数验证失败 : ", e);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, "参数验证失败");
}
/**
* 400 - Bad Request
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public BaseResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
logger.error("参数验证失败", e);
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String field = error.getField();
String code = error.getDefaultMessage();
String message = String.format("%s:%s", field, code);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, message);
}
/**
* 500 - INTERNAL_SERVER_ERROR
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(FeignException.class)
public BaseResult handleMethodFeignException(FeignException e) {
logger.error("参数验证失败", e);
return BaseResult.failure(BaseResult.PARAMETER_ERROR, e.getMessage());
}
/**
* 500
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(MyRuntimeException.class)
public BaseResult runtimeException(MyRuntimeException e) {
logger.error(e.getMessage(), e);
return BaseResult.failure(BaseResult.FAILURE, e.getMessage());
}
/**
* 500 - INTERNAL_SERVER_ERROR
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(RuntimeException.class)
public BaseResult runtimeException(RuntimeException e) {
logger.error(e.getMessage(), e);
return BaseResult.failure(BaseResult.FAILURE, e.getMessage());
}
/**
* 500 - INTERNAL_SERVER_ERROR
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(NullPointerException.class)
public BaseResult nullPointerException(NullPointerException e) {
e.printStackTrace();
logger.error("空指针异常,请查看系统日志", e);
return BaseResult.failure(BaseResult.FAILURE, "空指针异常,请查看系统日志");
}
/**
* 内部错误
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(NestedRuntimeException.class)
public BaseResult nestedRuntimeException(NestedRuntimeException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
return BaseResult.failure(BaseResult.FAILURE, e.getMessage());
}
/**
* 登录异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BadCredentialsException.class)
public BaseResult badCredentialsException(BadCredentialsException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
return BaseResult.failure(BaseResult.FAILURE, e.getMessage());
}
/**
* 缺少token, 或无效token, 或token过期
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(TokenException.class)
public BaseResult badCredentialsException(TokenException e) {
e.printStackTrace();
logger.error("缺少token, 或无效token, 或token过期", e);
return BaseResult.failure(BaseResult.TOKEN_FAILURE, "缺少token, 或无效token, 或token过期");
}
/**
* 调用频率过高时直接返回成功
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(CallFrequencyException.class)
public BaseResult badCredentialsException(CallFrequencyException e) {
logger.info(e.getUrl() + " 调用频率过高");
return BaseResult.success();
}
}
3、anti-counterfeiting.js
const app = getApp();
Page({
data: {
// 其他数据属性
},
// 扫描二维码
startScan: function() {
wx.scanCode({
onlyFromCamera: false, // 允许从相机和相册中选择图片
success: (res) => {
const code = res.result;
console.log("扫描结果:", code);
this.checkAntiFakeCode(code);
},
fail: (err) => {
wx.showToast({
title: '扫描失败,请重试',
icon: 'none'
});
}
});
},
// 校验防伪码
async checkAntiFakeCode(code) {
try {
const token = wx.getStorageSync('token');
if (!token) {
wx.showToast({
title: '获取 token 失败,请重试',
icon: 'none'
});
return;
}
// 获取用户的地理位置
const location = await app.getLocation();
const latitude = location.latitude;
const longitude = location.longitude;
console.log('获取地理位置成功:', { latitude, longitude });
const latitudeStr = latitude.toString();
const longitudeStr = longitude.toString();
console.log(latitudeStr); // 输出纬度的字符串形式
console.log(longitudeStr); // 输出经度的字符串形式
// 获取用户的 unionId
const unionId = '';
// 获取品牌ID
const brandId = 61; // 示例品牌ID,实际应用中需要从其他地方获取
// 构建请求参数
const requestData = {
code: code,
latitude: latitude.toString(),
longitude: longitude.toString(),
unionId: unionId,
brandId: brandId
};
console.log("请求数据:", requestData);
const response = await new Promise((resolve, reject) => {
wx.request({
//url: 'https://api.crossbiog.com/antiFake/check', // 使用配置文件中的URL
url:'http://localhost:8087/antiFake/check',
method: 'POST',
data: requestData,
header: {
'token': token,
'Content-Type': 'application/x-www-form-urlencoded'
},
success: resolve,
fail: reject
});
});
console.log("response:" + JSON.stringify(response))
if (response.statusCode === 200) {
const result = response.data;
if (result.code === 0) {
wx.showToast({
title: '防伪码验证成功',
icon: 'success'
});
// 跳转到防伪查询页面,并传递必要的参数
wx.navigateTo({
url: `/components/antiFakeQuery/antiFakeQuery?code=${code}&result=${encodeURIComponent(result.msg)}`
});
} else {
wx.showToast({
title: result.msg,
icon: 'none'
});
}
} else {
wx.showToast({
title: '请求失败,状态码: ${response.statusCode}',
icon: 'none'
});
}
} catch (error) {
wx.showToast({
title: error.message || '请求失败',
icon: 'none'
});
console.error('请求失败:', error); // 打印详细的错误信息
}
},
});
4、AntiFakeController
@Api(description = "防伪码")
@RequestMapping("antiFake")
@RestController
public class AntiFakeController {
@ApiOperation(value = "校验防伪码")
@PostMapping("check")
@PassToken
public BaseResult check(@ApiParam("防伪码") @RequestParam("code") String code,
@ApiParam("纬度") @RequestParam("latitude") String latitude,
@ApiParam("经度") @RequestParam("longitude") String longitude,
@ApiParam("微信ID") @RequestParam("unionId") String unionId,
@ApiParam("品牌ID") @RequestParam("brandId") Integer brandId) {
AntiFake antiFake = antiFakeService.findByCode(code);
if (antiFake == null) {
return BaseResult.failure(601, "当前防伪码不存在");
}
if (!brandId.equals(antiFake.getBrandId())) {
return BaseResult.failure(604, "非当前品牌防伪码");
}
BaseResult result = null;
switch (antiFake.getStatus()) {
case AntiFake.STATUS_UNACTIVAT:
result = BaseResult.failure(602, "当前防伪码未激活");
break;
case AntiFake.STATUS_LOCKED:
result = BaseResult.failure(603, "当前防伪码已被锁定");
break;
case AntiFake.STATUS_NORMAL:
result = BaseResult.success();
if (antiFake.getCheckNumber() == 0) {
antiFake.setFirstCheckDate(new Date());
}
antiFake.setCheckNumber(antiFake.getCheckNumber() + 1);
antiFake = antiFakeService.save(antiFake);
break;
default:
}
AntiFakeCheckRecord antiFakeCheckRecord = new AntiFakeCheckRecord();
antiFakeCheckRecord.setAntiFakeId(antiFake.getId());
antiFakeCheckRecord.setLatitude(latitude);
antiFakeCheckRecord.setLongitude(longitude);
antiFakeCheckRecord.setAddress(AddressUtil.getAddress(latitude, longitude));
antiFakeCheckRecord.setUnionId(unionId);
antiFakeCheckRecord.setResult(result.getMsg());
antiFakeCheckRecord.setCheckNumber(antiFake.getCheckNumber());
antiFakeCheckRecordService.save(antiFakeCheckRecord);
result.setData(antiFake);
return result;
}
}
5、解决方案
在你的后端代码中,check
方法使用了 @RequestParam
注解来接收 code
、latitude
、longitude
、unionId
和 brandId
参数。这意味着这些参数应当以查询参数的形式传递,而不是以 JSON 格式发送在请求体中。
要解决 MissingServletRequestParameterException
问题,可以从前端发送请求时确保参数按 application/x-www-form-urlencoded
或 URL 查询参数形式传递。以下是几种处理方式:
方案一:修改前端请求格式
在前端将数据改为 URL 查询字符串格式,并设置请求头为 application/x-www-form-urlencoded
,如下所示:
const requestData = `code=${code}&latitude=${latitude}&longitude=${longitude}&unionId=${unionId}&brandId=${brandId}`;
wx.request({
url: 'http://localhost:8087/antiFake/check',
method: 'POST',
data: requestData,
header: {
'token': token,
'Content-Type': 'application/x-www-form-urlencoded'
},
success: resolve,
fail: reject
});
方案二:拼接 URL 参数(适用于 GET
请求或带参数的 POST
请求)
如果后端允许将请求参数直接作为 URL 查询参数传递,可以将参数拼接到 URL 中:
const url = `http://localhost:8087/antiFake/check?code=${code}&latitude=${latitude}&longitude=${longitude}&unionId=${unionId}&brandId=${brandId}`;
wx.request({
url: url,
method: 'POST',
header: {
'token': token,
'Content-Type': 'application/json'
},
success: resolve,
fail: reject
});
方案三:后端改用 @RequestBody
如果必须以 JSON 格式发送请求体,建议将后端方法的参数改为 @RequestBody
,使其接收 JSON 格式数据:
@PostMapping("check")
public BaseResult check(@RequestBody Map<String, Object> requestData) {
String code = (String) requestData.get("code");
String latitude = (String) requestData.get("latitude");
String longitude = (String) requestData.get("longitude");
String unionId = (String) requestData.get("unionId");
Integer brandId = (Integer) requestData.get("brandId");
// 接下来的逻辑保持不变
}
这样前端可以继续使用 JSON 格式发送数据,不需要修改请求头。
总结
如果你不想修改后端代码,建议使用方案一或方案二,以确保 @RequestParam
能正确接收到数据。