如何通过fasterxml反序列化数组?

时间:2016-01-27 09:11:27

标签: java json fasterxml

我有以下课程

@JsonIgnoreProperties({"error"})
public class GetReceiptResponse {
    //Cashier Id
    public String cid;
    //Created
    public String time;
    //TotalAmount
    public String ta;
    //Cash amount
    public String cash;
    //Card amount
    public String card;
    //PartialPayment amount
    public String ppa;
    //PrePaymentUsage amount
    public String ppu;
    //Lottery number
    public String lot;
    //OperationType(0 = ORDER, 2 = RETURN, 3 = PREPAYMENT)
    public String type;
    //Referenced Receipt Id
    public String ref;
    //Referenced crn
    public String refcrn;

    //Products, or Departments
    @JsonDeserialize(as = SubTotal[].class)
    public SubTotal[] totals;

    public GetReceiptResponse() {
    }

    public class SubTotal {
        public String did;  //Department Id
        public String dt;   //Department Tax
        public String dtm;  //Department Tax Mode
        public String t;    //Total
        public String tt;   //Total With Tax
        public String id;   //Product Id
        public String gc;   //Good Code
        public String gn;   //Good Name
        public String qty;  //Quantity
        public String p;    //Price
        public String adg;  //ATG Code
        public String mu;   //Measurement Unit
        public String dsc;  //Discount
        public String adsc; //AdditionalDiscount
        public String dsct; //DiscountType
        public String rpid; //ReceiptProductId

        public SubTotal() {
        }
    }

}

这是json我得到了

{
    "time": 1453881919000,
    "lot": "28543833",
    "type": 0,
    "cid": 3,
    "ta": 6000,
    "cash": 6000,
    "card": 0,
    "ppa": 0,
    "ppu": 0,
    "saleType": 2,
    "totals": [
        {
            "gc": "002",
            "gn": "Fanta",
            "qty": 3,
            "p": 1000,
            "mu": "տուփ",
            "rpid": 1,
            "did": 1,
            "dt": 16.67,
            "dtm": 1,
            "t": 2499.9,
            "tt": 3000
        },
        {
            "gc": "001",
            "gn": "Coca Cola",
            "qty": 3,
            "p": 1000,
            "mu": "տուփ",
            "rpid": 0,
            "did": 1,
            "dt": 16.67,
            "dtm": 1,
            "t": 2499.9,
            "tt": 3000
        }
    ]
}

但我得到了一个例外

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class am.iunetworks.ecr.client.V04.pojo.GetReceiptResponse$SubTotal]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: [B@44e3a2b2; line: 1, column: 169] (through reference chain: am.iunetworks.ecr.client.V04.pojo.GetReceiptResponse["totals"])

我已经注释了该成员作为json deserilize的数组类型,你可以看到,但仍然没有结果。

我该怎么做?

提前致谢

1 个答案:

答案 0 :(得分:1)

尝试使内部类ststic。杰克逊需要访问它:#import "MessageManager.h" #import "DDLog.h" #import "DDTTYLogger.h" #import <CFNetwork/CFNetwork.h> #if DEBUG static const int ddLogLevel = LOG_LEVEL_VERBOSE; #else static const int ddLogLevel = LOG_LEVEL_INFO; #endif @interface MessageManager() @end static MessageManager *sharedMessageHandler = nil; @implementation MessageManager @synthesize xmppStream; @synthesize xmppRoster; @synthesize xmppRosterStorage; @synthesize xmppRoom; #pragma mark - self class Delegate - (void) setdelegate:(id)delegate { _delgate= delegate; } - (id) delegate { return _delgate; } #pragma mark - custom Functions + (MessageManager *) sharedMessageHandler { if (sharedMessageHandler == nil) { sharedMessageHandler = [[super allocWithZone:NULL] init]; } return sharedMessageHandler; } + (id)allocWithZone:(NSZone *)zone { return [self sharedMessageHandler]; } - (id)copyWithZone:(NSZone *)zone { return self; } #pragma mark - connection setup Functions /** This fuction is used to setup XMPP Stream */ - (void)setupStream { // Setup xmpp stream // // The XMPPStream is the base class for all activity. // Everything else plugs into the xmppStream, such as modules/extensions and delegates. xmppStream = [[XMPPStream alloc] init]; [xmppStream setHostName:kBaseXMPPURL]; [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; } /** This fuction is used to Connect XMPP With userId and Password */ - (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword { [self setupStream]; isRegistering=NO; if (![xmppStream isDisconnected]) { return YES; } if (jabberID == nil || myPassword == nil) { return NO; } [xmppStream setMyJID:[XMPPJID jidWithString:jabberID]]; password = myPassword; NSError *error = nil; if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Can't connect to server %@", [error localizedDescription]] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alertView show]; return NO; } return YES; } - (void) authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword { if ([xmppStream isConnected]) { NSError*error =nil; [xmppStream setMyJID:[XMPPJID jidWithString:userName]]; [xmppStream authenticateWithPassword:myPassword error:&error]; } else { [self connectWithUserId:userName withPassword:myPassword]; } } #pragma mark ---Delegate of Connect /** This fuction is called when stream is connected */ - (void)xmppStreamDidConnect:(XMPPStream *)sender { isOpen = YES; NSError *error = nil; NSLog(@"Stream Connected"); if (!isRegistering) { if([[self delegate] respondsToSelector:@selector(didGetStreamState:)]) { [[self delegate]didGetStreamState:YES]; } [xmppStream authenticateWithPassword:password error:&error]; } else { [xmppStream registerWithPassword:password error:&error]; } } /** This fuction is called when User is Authenticated */ - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender { [self goOnline]; NSLog(@"Stream Authenticated"); if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)]) { [[self delegate]didGetAuthenticationState:YES]; } if ([xmppStream isAuthenticated]) { NSLog(@"authenticated"); xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore]; xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage]; [xmppvCardTempModule activate:[self xmppStream]]; [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()]; [xmppvCardTempModule fetchvCardTempForJID:[sender myJID] ignoreStorage:YES]; } } - (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid{ NSLog(@"Delegate is called"); XMPPvCardTemp *vCard = [xmppvCardStorage vCardTempForJID:jid xmppStream:xmppStream]; NSLog(@"Stored card: %@",vCard); NSLog(@"%@", vCard.description); NSLog(@"%@", vCard.name); NSLog(@"%@", vCard.emailAddresses); NSLog(@"%@", vCard.formattedName); NSLog(@"%@", vCard.givenName); NSLog(@"%@", vCard.middleName); } /** This fuction is called when User is not Authenticated */ - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error { NSLog(@"Not Authenticated"); if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)]) { [[self delegate]didGetAuthenticationState:NO]; } } #pragma mark - Stream disconnection /** This fuction is used to disconnet user */ - (void)disconnect { [self goOffline]; [xmppStream disconnect]; } #pragma mark ---Delegate of disconnect /** This fuction is called when stream is disConnected */ - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error { NSLog(@"Stream Disconnected"); if([[self delegate] respondsToSelector:@selector(didGetStreamState:)]) { [[self delegate]didGetStreamState:NO]; } } #pragma mark - setting presence /** This fuction is used change the presence to online */ - (void)goOnline { XMPPPresence *presence = [XMPPPresence presence]; [xmppStream sendElement:presence]; } /** This fuction is used change the presence to Ofline */ - (void)goOffline { XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"]; [xmppStream sendElement:presence]; } /** This fuction is used change the presence substate */ - (void) presenceWithStubState:(NSString*)subState { XMPPPresence *presence = [XMPPPresence presence];// type="available" is implicit NSXMLElement *status = [NSXMLElement elementWithName:@"status"]; [status setStringValue:subState]; [presence addChild:status]; [xmppStream sendElement:presence]; } /** This fuction is called when other user state is changed */ - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence { DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]); NSString *presenceType = [presence type]; // online/offline NSString *myUsername = [[sender myJID] user]; NSString *presenceFromUser = [[presence from] user]; NSString* presenceState= [presence status]; NSLog(@"%@ is %@ state %@",presenceFromUser,presenceType,presenceState); if (![presenceFromUser isEqualToString:myUsername]) { if ([presenceType isEqualToString:@"available"]) { if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)]) { [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState]; } } else if ([presenceType isEqualToString:@"unavailable"]) { if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)]) { [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState]; } } else if ([presenceType isEqualToString:@"subscribe"]) { [xmppRoster subscribePresenceToUser:[presence from]]; [self goOnline]; } else if ([presenceType isEqualToString:@"subscribed"]) { [xmppRoster subscribePresenceToUser:[presence from]]; } } if (xmppRoom) { [xmppRoom fetchMembersList]; } } #pragma mark - subscription - (void) sendSubscribeMessageToUser:(NSString*)userID { XMPPJID* jbid= [XMPPJID jidWithString:userID]; XMPPPresence *presence = [XMPPPresence presenceWithType:@"subscribe" to:jbid]; [xmppStream sendElement:presence]; } #pragma mark - XMPP delegates /** This fuction is called when new IQ is received */ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq { return NO; } #pragma mark - RegistrationFunction /** This fuction is user to retister new user if stream is connected the it will directly call registeration function otherwise it will connect stream and then call registeration process */ - (void)registerStudentWithUserName:(NSString *)userName withPassword:(NSString *)_password withEmailId:(NSString *)EmailId { if (xmppStream==nil) { [self setupStream]; } [xmppStream setMyJID:[XMPPJID jidWithString:userName]]; NSLog(@"Attempting registration for username %@",xmppStream.myJID.bare); password=_password; NSError *error = nil; BOOL success; if(![ xmppStream isConnected]) { success = [[self xmppStream] connectWithTimeout:XMPPStreamTimeoutNone error:&error]; isRegistering=YES; } else { success = [[self xmppStream] registerWithPassword:_password error:&error]; } if (success) { NSLog(@"succeed "); isRegistering=YES; } else { if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)]) { [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Stream not connected"]; } } } #pragma mark ---delegates of registrtaion /** This fuction is called when new user is registered */ - (void)xmppStreamDidRegister:(XMPPStream *)sender{ if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)]) { [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Registration with XMPP Successful!"]; } } /** This fuction is called when registeration process failed */ - (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{ // DDXMLElement *errorXML = [error elementForName:@"error"]; // NSString *errorCode = [[errorXML attributeForName:@"code"] stringValue]; // NSString *regError = [NSString stringWithFormat:@"ERROR :- %@",error.description]; // // // if([errorCode isEqualToString:@"409"]) // { // regError=@"Username Already Exists!"; // } // else // { // regError= @"Server not connected"; // } if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)]) { [[self delegate]didGetRegistrationState:NO WithErrorMessage:@"Username Already Exists!"]; } } #pragma mark - send and recieve message /** This fuction is used to send message to other user with contents of body */ //-(void)sendMessageTo:(NSString*)toAdress withContents:(NSString*)messageStr //{ // // // if([messageStr length]> 0) // { // // NSXMLElement *body = [NSXMLElement elementWithName:@"body"]; // [body setStringValue:messageStr]; // // NSXMLElement *message = [NSXMLElement elementWithName:@"message"]; // [message addAttributeWithName:@"type" stringValue:@"chat"]; // [message addAttributeWithName:@"to" stringValue:toAdress]; // [message addChild:body]; // // [self.xmppStream sendElement:message]; // } //} - (BOOL)sendMessageTo:(NSString*)toAdress withContents:(NSString*)content { if([content length]> 0) { NSXMLElement *body = [NSXMLElement elementWithName:@"body"]; [body setStringValue:content]; NSXMLElement *message = [NSXMLElement elementWithName:@"message"]; [message addAttributeWithName:@"type" stringValue:@"chat"]; [message addAttributeWithName:@"to" stringValue:toAdress]; [message addChild:body]; [self.xmppStream sendElement:message]; } return YES; } #pragma mark recieve message /** This fuction is called when new message arrived */ - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message { DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD); // A simple example of inbound message handling. if ([message body]) { NSString *body = [[message elementForName:@"body"] stringValue]; if([[self delegate] respondsToSelector:@selector(didReceiveMessageWithBody:)]) { [[self delegate] didReceiveMessageWithBody:body]; } } } #pragma mark - create new room /** This fuction is used to setup room with roomId */ -(void)setUpRoom:(NSString *)ChatRoomJID { if (!ChatRoomJID) { return; } // Configure xmppRoom XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init]; XMPPJID *roomJID = [XMPPJID jidWithString:ChatRoomJID]; xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage jid:roomJID dispatchQueue:dispatch_get_main_queue()]; [xmppRoom activate:xmppStream]; [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()]; NSXMLElement *history = [NSXMLElement elementWithName:@"history"]; [history addAttributeWithName:@" maxchars" stringValue:@"0"]; [xmppRoom joinRoomUsingNickname:xmppStream.myJID.user history:history password:nil]; [self performSelector:@selector(ConfigureNewRoom:) withObject:nil afterDelay:4]; } /** This fuction is used configure new */ - (void)ConfigureNewRoom:(id)sender { [xmppRoom configureRoomUsingOptions:nil]; [xmppRoom fetchConfigurationForm]; [xmppRoom fetchBanList]; [xmppRoom fetchMembersList]; [xmppRoom fetchModeratorsList]; } /** This fuction is called when new room is created */ - (void)xmppRoomDidCreate:(XMPPRoom *)sender { DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD); // I am inviting friends after room is created } /** This fuction is called when user joined room */ - (void)xmppRoomDidJoin:(XMPPRoom *)sender { [sender fetchMembersList]; [sender fetchConfigurationForm]; [self requestAllMesssage]; DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD); if([[self delegate] respondsToSelector:@selector(didCreatedOrJoinedRoomWithCreatedRoomName:)]) { [[self delegate] didCreatedOrJoinedRoomWithCreatedRoomName:sender.myRoomJID.bare]; } } - (void)xmppRoom:(XMPPRoom *)sender didFetchMembersList:(NSArray *)items { } - (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence { if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)]) { // id details =occupantJID; // NSString* string = (NSString*)details; [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]]; } } - (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence { if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)]) { [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]]; } } - (void)xmppRoom:(XMPPRoom *)sender occupantDidUpdate:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence { if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)]) { [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]]; } } - (void) requestAllMesssage { // <presence // from='hag66@shakespeare.lit/pda' // id='n13mt3l' // to='coven@chat.shakespeare.lit/thirdwitch'> // <x xmlns='http://jabber.org/protocol/muc'> // <history since='1970-01-01T00:00:00Z'/> // </x> // </presence> // // NSXMLElement *iQ = [NSXMLElement elementWithName:@"presence"]; // [iQ addAttributeWithName:@"type" stringValue:@"get"]; // [iQ addAttributeWithName:@"id" stringValue:@"n13mt3l"]; // // NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve"]; // [retrieve addAttributeWithName:@"xmlns" stringValue:@"urn:xmpp:archive"]; // [retrieve addAttributeWithName:@"history since" stringValue:@"1970-01-01T00:00:00Z"]; // // NSXMLElement *set = [NSXMLElement elementWithName:@"set"]; // [set addAttributeWithName:@"xmlns" stringValue:@"http://jabber.org/protocol/muc"]; // // [retrieve addChild:set]; // [iQ addChild:retrieve]; // // [xmppStream sendElement:iQ]; } - (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm { DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD); NSXMLElement *newConfig = [configForm copy]; NSArray *fields = [newConfig elementsForName:@"field"]; for (NSXMLElement *field in fields) { NSString *var = [field attributeStringValueForName:@"var"]; // Make Room Persistent if ([var isEqualToString:@"muc#roomconfig_persistentroom"]) { [field removeChildAtIndex:0]; [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]]; } if ([var isEqualToString:@"roomconfig_enablelogging"]) { [field removeChildAtIndex:0]; [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]]; } if ([var isEqualToString:@"muc#roomconfig_maxusers"]) { [field removeChildAtIndex:0]; [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"100"]]; } } // [sender configureRoomUsingOptions:newConfig]; } /** This fuction is used to destroy created room */ - (void) destroyCreatedRoom { [xmppRoom destroyRoom]; } - (BOOL)sendGroupMessageWithBody:(NSString*)_body { [xmppRoom sendMessageWithBody:_body]; return YES; } @end