ninja-core/src/main/java/ninja/bodyparser/BodyParserEnginePost.java
private <T> T invoke(Context context, Map<String, String[]> parameters, Class<T> classOfT, String paramPrefix) {
        
        T t = null;

        try {
            t = classOfT.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            logger.error("Can't create new instance of class {}", classOfT.getName(), e);
            return null;
        }

        for (String declaredField : getAllDeclaredFieldsAsStringSet(classOfT)) {

            try {

                Field field = classOfT.getDeclaredField(declaredField);
                Class<?> fieldType = field.getType();
                field.setAccessible(true);

                if (parameters.containsKey(paramPrefix + declaredField)) {
                    
                    String[] values = parameters.get(paramPrefix + declaredField);

                    if (Collection.class.isAssignableFrom(fieldType) || List.class.isAssignableFrom(fieldType)) {

                        ListParamParser<?> parser = (ListParamParser<?>) paramParsers.getListParser(getGenericType(field));
                        if (parser == null) {
                            logger.warn("No parser defined for a collection of type {}", getGenericType(field).getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                        }

                    } else if (fieldType.isArray()) {

                        ArrayParamParser<?> parser = paramParsers.getArrayParser(fieldType);
                        if (parser == null) {
                            logger.warn("No parser defined for an array of type {}", fieldType.getComponentType().getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                        }

                    } else {

                        ParamParser<?> parser = (ParamParser<?>) paramParsers.getParamParser(fieldType);
                        if (parser == null) {
                            logger.warn("No parser defined for type {}", fieldType.getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values[0], context.getValidation()));
                        }

                    }

                } else {
                    
                    // Check if we have one parameter key corresponding to one valued inner attribute of this object field
                    for (String parameter : parameters.keySet()) {
                        if(parameter.startsWith(paramPrefix + declaredField + ".")) {
                            if(isEmptyParameter(parameters.get(parameter))) {
                                field.set(t, invoke(context, parameters, fieldType, paramPrefix + declaredField + "."));
                                break;
                            }
                        }
                    }
                    
                }

            } catch (NoSuchFieldException 
                    | SecurityException 
                    | IllegalArgumentException 
                    | IllegalAccessException e) {

                logger.warn(
                        "Error parsing incoming Post request into class {}. Key {} and value {}.", 
                        classOfT.getName(), paramPrefix + declaredField, parameters.get(paramPrefix + declaredField), e);
            }

        }
        return t;
    }
private <T> T invoke(Context context, Map<String, String[]> parameters, Class<T> classOfT, String paramPrefix) {
        
        T t = null;

        try {
            t = classOfT.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            logger.error("Can't create new instance of class {}", classOfT.getName(), e);
            return null;
        }

        for (String declaredField : getAllDeclaredFieldsAsStringSet(classOfT)) {

            try {

                Field field = classOfT.getDeclaredField(declaredField);
                Class<?> fieldType = field.getType();
                field.setAccessible(true);

                if (parameters.containsKey(paramPrefix + declaredField)) {
                    
                    String[] values = parameters.get(paramPrefix + declaredField);

                    if (Collection.class.isAssignableFrom(fieldType) || List.class.isAssignableFrom(fieldType)) {

                        ListParamParser<?> parser = (ListParamParser<?>) paramParsers.getListParser(getGenericType(field));
                        if (parser == null) {
                            logger.warn("No parser defined for a collection of type {}", getGenericType(field).getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                        }

                    } else if (fieldType.isArray()) {

                        ArrayParamParser<?> parser = paramParsers.getArrayParser(fieldType);
                        if (parser == null) {
                            logger.warn("No parser defined for an array of type {}", fieldType.getComponentType().getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values, context.getValidation()));
                        }

                    } else {

                        ParamParser<?> parser = (ParamParser<?>) paramParsers.getParamParser(fieldType);
                        if (parser == null) {
                            logger.warn("No parser defined for type {}", fieldType.getCanonicalName());
                        } else {
                            field.set(t, parser.parseParameter(field.getName(), values[0], context.getValidation()));
                        }

                    }

                } else {
                    
                    // Check if we have one parameter key corresponding to one valued inner attribute of this object field
                    for (String parameter : parameters.keySet()) {
                        if(parameter.startsWith(paramPrefix + declaredField + ".")) {
                            if(isEmptyParameter(parameters.get(parameter))) {
                                field.set(t, invoke(context, parameters, fieldType, paramPrefix + declaredField + "."));
                                break;
                            }
                        }
                    }
                    
                }

            } catch (NoSuchFieldException 
                    | SecurityException 
                    | IllegalArgumentException 
                    | IllegalAccessException e) {

                logger.warn(
                        "Error parsing incoming Post request into class {}. Key {} and value {}.", 
                        classOfT.getName(), paramPrefix + declaredField, parameters.get(paramPrefix + declaredField), e);
            }

        }
        return t;
    }
Allows to instantiate inner objects with a prefix for each parameter key