首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试访问节点类型(用户)上不存在的字段(上下文)

尝试访问节点类型(用户)上不存在的字段(上下文)
EN

Stack Overflow用户
提问于 2019-08-15 12:46:29
回答 5查看 5.6K关注 0票数 3

我正在从connection.fetchUserProfile()访问Connection<?> connection,但它提供了org.springframework.social.UncategorizedApiException: (#100) Tried accessing nonexisting field (context) on node type (User)。这种特殊的错误以前从来没有发生过。

maven:

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
     <version>3.0.0.M3</version>
</dependency>

知道为什么会这样吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-08-29 07:34:09

我也有同样的问题,到处寻找解决办法。在没有任何运气的情况下,我最终编写了一个自定义服务,该服务调用Facebook并填充UserProfile对象。

向项目中添加一个新的FBService.java类:

代码语言:javascript
复制
package net.attacomsian.services;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.social.connect.UserProfile;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@Service
public class FBService {

    private final RestTemplate restTemplate;

    public FBService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    public UserProfile getProfile(String id, String accessToken) {
        try {
            //params
            String params = "fields=id,name,email,first_name,last_name&access_token=" + accessToken;

            //build url
            String url = "https://graph.facebook.com/v3.2/" + id + "?" + params;

            //create headers
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

            // create request
            HttpEntity request = new HttpEntity(headers);

            //use rest template
            ResponseEntity<String> response = this.restTemplate.exchange(url, HttpMethod.GET, request, String.class);

            //check for status code
            if (response.getStatusCode().is2xxSuccessful()) {
                JsonNode root =  new ObjectMapper().readTree(response.getBody());

                // return a user profile object
                return new UserProfile(root.path("id").asText(), root.path("name").asText(), root.path("first_name").asText(),
                        root.path("last_name").asText(), root.path("email").asText(), null);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }
}

v3.2是Graph版本。代之以你自己的。现在将此服务注入控制器,而不是调用:

代码语言:javascript
复制
UserProfile profile = connection.fetchUserProfile();

调用新服务getProfile()方法,如下所示:

代码语言:javascript
复制
Profile profile = fbService.getProfile("me", connection.createData().getAccessToken());

对我来说就像魔法一样。

Update:这里是完整的web控制器代码,它展示了如何为Facebook使用自定义服务,同时继续为Google的用户配置文件使用默认的服务:

代码语言:javascript
复制
@Controller
public class AuthController {

    private FBService fbService;
    private final ProviderSignInUtils providerSignInUtils;

    public AuthController(FBService fbService,
                          ConnectionFactoryLocator connectionFactoryLocator,
                          UsersConnectionRepository connectionRepository) {
        this.fbService = fbService;
        this.providerSignInUtils = new ProviderSignInUtils(connectionFactoryLocator, connectionRepository);
    }

    @GetMapping("/social-signup")
    public String socialSignup(WebRequest request, HttpSession session) {

        Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);
        if (connection == null) {
            return "redirect:/login";
        }

        //fetch user information
        UserProfile profile = null;
        if (connection.getKey().getProviderId().equalsIgnoreCase("google")) {
            profile = connection.fetchUserProfile();
        } else if (connection.getKey().getProviderId().equalsIgnoreCase("facebook")) {
            profile = fbService.getProfile("me", connection.createData().getAccessToken());
        }

        // TODO: continue doing everything else
    }
}
票数 4
EN

Stack Overflow用户

发布于 2019-11-24 19:42:28

看起来facebook社交网站将不再更新。

无论如何,我不想花时间切换到另一个库。

我刚刚拿到了我需要的字段:

代码语言:javascript
复制
FacebookTemplate facebook = new FacebookTemplate(socialToken);

User facebookUser = facebook.fetchObject(FacebookUtils.LOGGED_USER_ID, User.class, FacebookUtils.USER_FIELD_ID, FacebookUtils.USER_FIELD_EMAIL,
            FacebookUtils.USER_FIELD_FIRST_NAME, FacebookUtils.USER_FIELD_LAST_NAME);

我已经添加到我的FacebookUtils中的字段:

代码语言:javascript
复制
/** The Constant LOGGED_USER_ID. */
public static final String LOGGED_USER_ID = "me";

/** The Constant USER_FIELD_ID. */
public static final String USER_FIELD_ID = "id";

/** The Constant USER_FIELD_EMAIL. */
public static final String USER_FIELD_EMAIL = "email";

/** The Constant USER_FIELD_FIRST_NAME. */
public static final String USER_FIELD_FIRST_NAME = "first_name";

/** The Constant USER_FIELD_LAST_NAME. */
public static final String USER_FIELD_LAST_NAME = "last_name";
票数 4
EN

Stack Overflow用户

发布于 2019-10-29 21:27:19

EDIT#2:这个问题又发生在我身上。如果您想知道如何修改某个包并将其添加到maven中,请继续读下去,但是如果您只是想知道如何消除该错误(以及其他类似的错误涉及不同的属性),那么您应该只需遵循这个答案中的建议: https://stackoverflow.com/a/34133450/754988. --它比我的要好得多。

虽然阿科姆森的解决方案可能对某些人有效,但我依赖于其他服务(如谷歌登录)的抽象UserProfile,而他们的解决方案将打破这一点。

我发现一种不那么有侵略性的操作方法是转到ss-facebook的github,按照他们的指令中的前两行从源代码构建:

代码语言:javascript
复制
git clone git://github.com/SpringSource/spring-social-facebook.git
cd spring-social-facebook

但是在运行./gradlew build命令之前,打开这个文件进行编辑:

代码语言:javascript
复制
./spring-social-facebook/src⁩/main⁩/java⁩/org⁩/springframework⁩/social⁩/facebook⁩/api⁩/UserOperations.java

向下滚动到底部,从数组中删除“上下文”,更改

代码语言:javascript
复制
static final String[] PROFILE_FIELDS = {
        "id", "about", "age_range", "birthday", "context", "cover", "currency", "devices", "education", "email", 

        ....

        "website", "work"
    };

代码语言:javascript
复制
static final String[] PROFILE_FIELDS = {
        "id", "about", "age_range", "birthday", "cover", "currency", "devices", "education", "email", 

        ....

        "website", "work"
    };

现在返回到源文件夹并运行最终命令:

代码语言:javascript
复制
./gradlew build

您将在那里得到一个./build文件夹,其中包含一个zip文件,解压缩它以找到您的工作罐子!我使用maven,用一些本地依赖项替换了我拥有的两个远程依赖项,如下所示:

代码语言:javascript
复制
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-facebook</artifactId>
            <version>3.0.0.M1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/spring-social-facebook-3.0.0.BUILD-SNAPSHOT.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-facebook-web</artifactId>
            <version>3.0.0.M1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/spring-social-facebook-web-3.0.0.BUILD-SNAPSHOT.jar</systemPath>
        </dependency>

编辑:,我已经了解到这并不是在Maven中包含这样一个定制jar的最佳方法。这是一个小兔子洞,实际上,它在那里的工作,像其他罐子在你的pom。通过运行这些命令手动安装我制作的两个jars (3.0.1337是我为避免名称冲突而编写的版本-不确定是否有必要),我最终使它工作得更好.

代码语言:javascript
复制
mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file -Dfile=web/src/main/resources/lib/spring-social-facebook-3.0.1337.BUILD-SNAPSHOT.jar -DgroupId=org.springframework.social -DartifactId=spring-social-facebook -Dversion=3.0.1337 -Dpackaging=jar -DlocalRepositoryPath=web/src/main/resources/local-repo -DgeneratePom=true

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file -Dfile=web/src/main/resources/lib/spring-social-facebook-web-3.0.1337.BUILD-SNAPSHOT.jar -DgroupId=org.springframework.social -DartifactId=spring-social-facebook-web -Dversion=3.0.1337 -Dpackaging=jar -DlocalRepositoryPath=web/src/main/resources/local-repo -DgeneratePom=true

...Into是我在pom中声明的本地存储库,如下所示:

代码语言:javascript
复制
<repositories>
  <repository>
    <id>local-repo</id>
    <url>file://${project.basedir}/src/main/resources/local-repo</url>
  </repository>
</repositories>

然后,我将jars添加到源代码管理中,并在gitignore中添加了一行,以忽略/src/main/resources/local-repo文件夹。

如果有更好的方法可以保留所有原始代码,只需从该文件末尾的数组中删除“上下文”字符串,并且希望避免使用简单的单数类替换或扩展名,那么请加入。我只是把所有这些都包括在内,因为这肯定会让我省下一天的时间,让我一个接一个地弄清楚每件事。

免责声明:,我不知道这可能会产生什么副作用,否则我不熟悉这个库。虽然我怀疑这会造成很大的伤害,而且这显然是这一领域的一个改进,但如果不花更多的时间在这个图书馆上工作,这种变化可能会产生影响,而我没有合理的远见。因此,我没有提供一个修改过的JAR,只为其他人写下了一些简单的说明。你得冒着自己的风险继续执行这些指令。

此外,我刚刚检查了许可证,如果您确实做了此更改,请确保您遵循以下说明:

代码语言:javascript
复制
      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

如果我漏掉了其他法律方面的东西,请发表意见让我知道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57509883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档