Salesforce APEX REST API问题:无法向@HttpPost函数传入JSON负载
问题排查:Salesforce APEX REST API JSON解析错误
我开发了一个APEX类实现RestResource,专门处理HTTP POST请求(REST API),用来创建平台事件。因为有number这类受保护关键字,所以选择手动解析传入的JSON负载。
测试时遇到异常:负载为空时,函数能正常进入try/catch逻辑;但负载包含字段时,会触发未捕获错误,错误信息如下:
{"message":"Unexpected parameter encountered during deserialization: message_id at [line:1, column:17]","errorCode":"JSON_PARSER_ERROR"}]'
测试用curl命令
curl -X POST -H "Authorization: Bearer xxxxxxxx" -H "Content-Type: application/json" -d '{ "message_id": "12345", "mobileNumber": "1234567890", "text": "This is a test message", "sim_card_number": "SIM123", "reception_date": "2023-10-18 14:30:00" }' "https://myinstanceoftest.sandbox.my.salesforce.com/services/apexrest/incomingTextMessages"
对应的APEX类代码
@RestResource(urlMapping='/incomingTextMessages/*') global with sharing class AC14_IncomingTextMessage { // Define the JSON structure to match the incoming data. global class IncomingTextMessage { public String message_id; public String mobileNumber; public String text; public String sim_card_number; public String reception_date; } // Define the response structure. global class Response { public String status; public String message; } @HttpPost global static Response createIncomingTextMessage(String jsonPayload) { System.debug('Received JSON Message: ' + jsonPayload); Response response = new Response(); try { Map<String, Object> jsonMap = (Map<String, Object>) JSON.deserializeUntyped(jsonPayload); // Create an instance of the IncomingTextMessage class and manually map the field "number" to "mobileNumber." IncomingTextMessage incomingMessage = new IncomingTextMessage(); incomingMessage.message_id = (String) jsonMap.get('message_id'); incomingMessage.mobileNumber = (String) jsonMap.get('number'); incomingMessage.text = (String) jsonMap.get('text'); incomingMessage.sim_card_number = (String) jsonMap.get('sim_card_number'); incomingMessage.reception_date = (String) jsonMap.get('reception_date'); // Create a new Platform Event and set its fields. IncomingTextMessage__e newEvent = new IncomingTextMessage__e( Message_Id__c = incomingMessage.message_id, mobileNumber__c = incomingMessage.mobileNumber, Text__c = incomingMessage.text, Sim_Card_Number__c = incomingMessage.sim_card_number, Reception_Date__c = DateTime.valueOf(incomingMessage.reception_date) ); // Publish the Platform Event. EventBus.publish(newEvent); response.status = 'Success'; response.message = 'Platform Event created successfully'; } catch (Exception e) { response.status = 'Error'; response.message = 'Error processing the request: ' + e.getMessage(); } return response; } }
问题根源
你的APEX方法定义了String jsonPayload作为参数,Salesforce会自动尝试将POST请求的JSON负载反序列化为这个参数对应的结构。但当你传入包含message_id等字段的JSON对象时,Salesforce无法将整个JSON对象映射到单个字符串参数,因此触发了JSON解析错误。
修复方案
直接通过RestContext.request.requestBody获取原始请求体,再手动解析,避免Salesforce自动反序列化参数。修改后的代码如下:
@RestResource(urlMapping='/incomingTextMessages/*') global with sharing class AC14_IncomingTextMessage { // 定义响应结构 global class Response { public String status; public String message; } @HttpPost global static Response createIncomingTextMessage() { // 直接获取请求体内容 String jsonPayload = RestContext.request.requestBody.toString(); System.debug('Received JSON Message: ' + jsonPayload); Response response = new Response(); try { Map<String, Object> jsonMap = (Map<String, Object>) JSON.deserializeUntyped(jsonPayload); // 手动映射字段,注意与curl请求的字段名匹配 String message_id = (String) jsonMap.get('message_id'); String mobileNumber = (String) jsonMap.get('mobileNumber'); String text = (String) jsonMap.get('text'); String sim_card_number = (String) jsonMap.get('sim_card_number'); String reception_date = (String) jsonMap.get('reception_date'); // 创建平台事件 IncomingTextMessage__e newEvent = new IncomingTextMessage__e( Message_Id__c = message_id, mobileNumber__c = mobileNumber, Text__c = text, Sim_Card_Number__c = sim_card_number, Reception_Date__c = DateTime.valueOf(reception_date) ); // 发布事件 EventBus.publish(newEvent); response.status = 'Success'; response.message = '平台事件创建成功'; } catch (Exception e) { response.status = 'Error'; response.message = '处理请求时出错: ' + e.getMessage(); } return response; } }
额外注意事项
- 原代码中
incomingMessage.mobileNumber = (String) jsonMap.get('number');与curl请求的字段mobileNumber不匹配,修正后才能正确获取手机号数据。 - 移除了无用的
IncomingTextMessage内部类,因为已经手动解析JSON,无需该类做结构映射。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

