Spring boot 尝试访问节点类型(用户)上不存在的字段(上下文)
我正在从Spring boot 尝试访问节点类型(用户)上不存在的字段(上下文),spring-boot,facebook-graph-api,spring-social,Spring Boot,Facebook Graph Api,Spring Social,我正在从连接连接访问connection.fetchUserProfile(),但它给出了org.springframework.social.uncategorizedapieException:(#100)尝试访问节点类型(用户)上不存在的字段(上下文)。这个特别的错误以前从未发生过,直到现在 马文: <dependency> <groupId>org.springframework.social</groupId> <artifac
连接连接访问connection.fetchUserProfile()
,但它给出了org.springframework.social.uncategorizedapieException:(#100)尝试访问节点类型(用户)上不存在的字段(上下文)
。这个特别的错误以前从未发生过,直到现在
马文:
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>3.0.0.M3</version>
</dependency>
org.springframework.social
春季社交facebook
3.0.0.M3
知道为什么会发生这种情况吗?我也有同样的问题,到处寻找解决方案。没有任何运气,我最终编写了一个自定义服务,调用Facebook Graph API并填充UserProfile
对象
将新的FBService.java
类添加到项目中:
package net.attacomsian.services;
导入com.fasterxml.jackson.databind.JsonNode;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入org.springframework.boot.web.client.RestTemplateBuilder;
导入org.springframework.http.*;
导入org.springframework.social.connect.UserProfile;
导入org.springframework.stereotype.Service;
导入org.springframework.web.client.rest模板;
导入java.util.Collections;
@服务
公共服务{
私有最终RestTemplate RestTemplate;
公共FBService(RestTemplateBuilder RestTemplateBuilder){
this.restTemplate=restTemplateBuilder.build();
}
公共用户配置文件getProfile(字符串id、字符串accessToken){
试一试{
//params
String params=“fields=id,name,email,first_name,last_name&access_token=“+accessToken;
//构建url
字符串url=”https://graph.facebook.com/v3.2/“+id+”?“+参数;
//创建标题
HttpHeaders=新的HttpHeaders();
setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
//创建请求
HttpEntity请求=新的HttpEntity(标头);
//使用rest模板
ResponseEntity response=this.restemplate.exchange(url,HttpMethod.GET,request,String.class);
//检查状态代码
if(response.getStatusCode().is2xxSuccessful()){
JsonNode root=newObjectMapper().readTree(response.getBody());
//返回用户配置文件对象
返回新的UserProfile(root.path(“id”).asText(),root.path(“name”).asText(),root.path(“first_name”).asText(),
root.path(“姓氏”).asText(),root.path(“电子邮件”).asText(),null);
}
}捕获(例外情况除外){
例如printStackTrace();
}
返回null;
}
}
v3.2
是图形API版本。换成你自己的。现在将此服务注入控制器,而不是调用:
UserProfile=connection.fetchUserProfile();
调用新服务getProfile()
方法,如下所示:
Profile Profile=fbService.getProfile(“me”,connection.createData().getAccessToken());
这对我来说就像一个魔术
更新:以下是完整的web控制器代码,显示了如何使用Facebook的自定义服务,同时继续使用Google用户配置文件的默认服务:
@控制器
公共类授权控制器{
私人服务;
私人最终供应商SignNutils供应商SignNutils;
公共授权控制器(FBService FBService,
ConnectionFactoryLocator ConnectionFactoryLocator,
用户连接存储库连接存储库){
this.fbService=fbService;
this.providerSignInUtils=新的providerSignInUtils(connectionFactoryLocator,connectionRepository);
}
@GetMapping(“/social signup”)
公共字符串socialSignup(WebRequest请求、HttpSession会话){
连接连接=providerSignInUtils.getConnectionFromSession(请求);
if(连接==null){
返回“重定向:/login”;
}
//获取用户信息
UserProfile=null;
if(connection.getKey().getProviderId().equalsIgnoreCase(“谷歌”)){
profile=connection.fetchUserProfile();
}else if(connection.getKey().getProviderId().equalsIgnoreCase(“facebook”)){
profile=fbService.getProfile(“me”,connection.createData().getAccessToken());
}
//TODO:继续做其他事情
}
}
编辑#2:我又碰到了这个问题。如果您想知道如何修改某个包并将其添加到maven,请继续阅读,但如果您只是想知道如何消除该错误(以及其他类似的错误,如涉及不同属性的错误),那么您应该只需遵循以下答案中的建议:它比我的好得多
虽然attacomsian的解决方案可能对某些人有效,但我依赖于谷歌登录等其他服务的抽象用户配置文件,他们的解决方案将为我打破这一局面
我发现,一种侵入性较小的方法是,按照他们的指令的前两行从源代码构建:
git clone git://github.com/SpringSource/spring-social-facebook.git
cd spring-social-facebook
但在运行/gradlew build
命令之前,请打开此文件进行编辑:
./spring-social-facebook/src/main/java/org/springframework/social/facebook/api/UserOperations.java
向下滚动至底部并从数组中删除“上下文”,更改
static final String[] PROFILE_FIELDS = {
"id", "about", "age_range", "birthday", "context", "cover", "currency", "devices", "education", "email",
....
"website", "work"
};
到
现在返回源文件夹并运行最后一个命令:
./gradlew build
你会在那里得到一个/build
文件夹,里面有一个zip文件,解压缩它就可以找到你的工作罐了!我使用maven,将我拥有的两个远程依赖项替换为一些本地依赖项,如下所示:
<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>
…进入我在pom中声明的本地存储库,如下所示:
<repositories>
<repository>
<id>local-repo</id>
<url>file://${project.basedir}/src/main/resources/local-repo</url>
</repository>
</repositories>
如果我遗漏了任何其他法律信息,请发表评论让我知道。在回答@JohnTD时,如果您使用多个社会关系,那么您只需执行以下操作即可合并@attacomsian a
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
<repositories>
<repository>
<id>local-repo</id>
<url>file://${project.basedir}/src/main/resources/local-repo</url>
</repository>
</repositories>
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
public void getProfile(Connection connection) {
UserProfile socialMediaProfile = getSocialUserProfile(connection);
.
.
}
/**
* Checks for facebook connection requests so that we can call a custom service
*
* @param connection
* @return
*/
private UserProfile getSocialUserProfile(Connection<?> connection) {
if (isFacebookConnection(connection)) {
return facebookService.getProfile("me", connection.createData().getAccessToken());
} else {
return connection.fetchUserProfile();
}
}
private boolean isFacebookConnection(Connection<?> connection) {
return connection.getApi().toString().indexOf("FacebookTemplate") != -1;
}
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);
/** 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";
// Patch: spring social facebook tries to get a removed "context" field
for (int i=0; i<UserOperations.PROFILE_FIELDS.length; i++) {
// To avoid error override with existing "ratings" field
if (UserOperations.PROFILE_FIELDS[i].equals("context")) {
UserOperations.PROFILE_FIELDS[i] = "ratings";
}
}