5

您好我正在尝试创建一个 apex 休息服务,但收到错误 Invalid type for Http* method: system.RestRequest

这是我收到此错误的功能。

  @RestResource(urlMapping='/v.9/scorecard/*') 
global with sharing class ScorecardRestSvc {

  /**
  * @date July 26, 2011
  * @description Update a question answer. 
  * @return Map<String,String> - results and boolean success message
  */

  @HttpPost
  global Static Map<String,String> doPut(RestRequest req, RestResponse res) {

    String answerId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
    string updateResult = 'Waiting to run';
    Map<String,String> returnMap = new Map<String,String>();
    returnMap.put('Success','True');

    // mark the participant as having no submission
      if(req.params.containsKey('deleteSubmission') && req.params.get('deleteSubmission').toLowerCase() == 'true') {
      markParticipantAsNoSubmission(req,res);
        returnMap.put('Message','Participant marked as no submission.');
        return returnMap;    
      } 

    try {

      if(!isValidId(answerId) || answerId.length() == 0) {
        returnMap.put('Method','Bulk');
        updateResult = updateObjectsFromXml(req,res);     
      } else {
        returnMap.put('Method','Single');
        updateResult = updateSingleAnswer(req,res);
      }

      returnMap.put('Update Result', updateResult);

      if(updateResult != 'All records updated successfully. ' && updateResult != 'All records updated successfully. Survey set to scored. No further changes allowed') {
        returnMap.put('Success','False');
      }     
    } catch(Exception e) {
      returnMap.put('Error',e.getMessage());
    } 

    return returnMap;   
  }

  private static void markParticipantAsNoSubmission(RestRequest req, RestResponse res) { 
    ID participantId = (ID)req.params.get('participantId');
    // get the participant and mark them as no submission
    Challenge_Participant__c cp = [select id, Has_Submission__c from Challenge_Participant__c 
      where id = :participantId];
    cp.Has_Submission__c = false;
    cp.Status__c = 'Submission Rejected';
    update cp;      
  }

  private static String updateObjectsFromXml(RestRequest req, RestResponse res) {

    string returnMessage = 'All records updated successfully. ';

    try {
      String xml = req.requestBody.toString().trim();
      System.debug('===================== here is the xml passed: ' + xml);
      List<sObject> updateList = parseUpdateXML(xml);

      //before we update we need to make sure this card is not scored
      List<QwikScore_Question_Answer__c> thisAns = [select QwikScore_Scorecard__r.Scored__c, QwikScore_Scorecard__c 
        from QwikScore_Question_Answer__c where id = :updateList[0].Id];

      if(thisAns[0].QwikScore_Scorecard__r.Scored__c) throw new customException('This scorecard has been marked as scored. No further updates are available.');

     // ScoringEngine.saveAnswers(thisAns[0].QwikScore_Scorecard__c, updateList);           

      if(req.params.containsKey('setScored') && req.params.get('setScored').toLowerCase() == 'true') {
      //  ScoringEngine.gradeScorecard(thisAns[0].QwikScore_Scorecard__c);
        returnMessage += 'Survey set to scored. No further changes allowed';        
      }

    } catch(Exception e) {
      returnMessage = e.getMessage();
    }

    return returnMessage;
  }

  private static String updateSingleAnswer(RestRequest req, RestResponse res) {

    String answerId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

    // get a map of all field in the member__c custom object
    Map<String, Schema.SObjectField> sObjectFieldsMap = Schema.SObjectType.QwikScore_Question_Answer__c.fields.getMap();
    // don't let them update the following fields -- use all lowercase for comparison
    Set<String> noUpdateFields = new Set<String>{'Answer_Value__c,QwikScore_Scorecard__c,Weighted_Score__c,Answer_Value__c,IsAnswered__c'};

    String returnMessage = 'All records updated successfully. ';

    try {

      QwikScore_Question_Answer__c qa = new QwikScore_Question_Answer__c(Id=id.ValueOf(answerId));

      for (String key : req.params.keySet()) {
        // only add params if they are valid field on the object and not on the no-update list
        if (sObjectFieldsMap.containsKey(key) && !noUpdateFields.contains(key.toLowerCase()))
          qa.put(key,req.params.get(key)); 
      }

      List<QwikScore_Question_Answer__c> thisAns = [select QwikScore_Scorecard__r.Scored__c,
        QwikScore_Scorecard__c from QwikScore_Question_Answer__c where id = :qa.Id];

      if(thisAns.isEmpty()) throw new customException('Could not locate answer with Id' + qa.Id);

      if(thisAns[0].QwikScore_Scorecard__r.Scored__c) throw new customException('This scorecard has been marked as scored. No further updates are available.');

      //ScoringEngine.saveAnswers(thisAns[0].QwikScore_Scorecard__c, new List<QwikScore_Question_Answer__c>{qa});

      if(req.params.containsKey('setScored') && req.params.get('setScored').toLowerCase() == 'true') {
        //ScoringEngine.gradeScorecard(thisAns[0].QwikScore_Scorecard__c);
        returnMessage += 'Scorecard set to scored. No further changes allowed';          
      }

    } catch(Exception e) {
      returnMessage = e.getMessage();
    }

    return returnMessage;     
  }

  /*******************************************
  Used to create a list of sObjects ready for updating from 
  XML data that would likely be passed in a request

  This method is pretty cool actually. You can pass it some XML
  formated in the way outlined previously and it will get you a list
  of objects ready for update. I think they all have to be of the same type
  though.
  *******************************************/
  private static List<sObject> parseUpdateXML(String Xml) {

    Map<Id,sObject> updates = new Map<Id,sObject>();  
    xml = xml.trim();
    Xmlstreamreader reader = new Xmlstreamreader(xml);
    Id lastId;
    string fieldName;
    Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
    Schema.SobjectType oType;

    while (reader.hasNext()) {

      if (reader.getEventType() == XmlTag.START_ELEMENT && reader.getLocalName().toLowerCase() == 'object') {

        if(oType == null) oType = gd.get(reader.getAttributeValueAt(0));

        sObject thisObject;
        if(reader.getAttributeLocalName(1) == 'id') thisObject= oType.newSObject(reader.getAttributeValueAt(1));

        if(thisObject != null) {
          updates.put(thisObject.id,thisObject);
          lastId = thisObject.id;
        }
      } else if(reader.getEventType() == XmlTag.START_ELEMENT && reader.getLocalName().toLowerCase() == 'field') {
        fieldName = reader.getAttributeValueAt(0);
        sObject thisObject = updates.get(lastId);
        reader.next();
        thisObject.put(fieldName,getDecodedString(reader));
        updates.put(thisObject.id,thisObject);  
      }
    reader.next();
    }

    return updates.values();

  }

  /*******************************************
  Test to see if a given string is a valid id
  ********************************************/
  public static Boolean isValidId(String s) {
    Id validId;
    try {
      validId = s;
      return true; 
    } catch (Exception ex) {
      return false;
    }
  } 

  public class customException extends Exception {}

  public static String getDecodedString(Xmlstreamreader reader) {
    return EncodingUtil.urlDecode(reader.getText(), 'UTF-8').trim();
  }

}

谁能告诉我为什么会收到这个错误以及如何纠正它?

4

1 回答 1

9

在 api 版本 24.0 中访问 RestRequest 和 RestResponse 的方式发生了变化,因此任何 24.0 或更高版本的代码都需要使用新的 RestContext 对象来访问它们:

新方法

@HttpPost
global Static Map<String,String> doPut() {
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;

老路

@HttpPost
global Static Map<String,String> doPut(RestRequest req, RestResponse res) {
于 2012-07-24T04:59:43.910 回答