我正在从connection.fetchUserProfile()访问Connection<?> connection,但它提供了org.springframework.social.UncategorizedApiException: (#100) Tried accessing nonexisting field (context) on node type (User)。这种特殊的错误以前从来没有发生过。
maven:
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>3.0.0.M3</version>
</dependency>知道为什么会这样吗?
发布于 2019-08-29 07:34:09
我也有同样的问题,到处寻找解决办法。在没有任何运气的情况下,我最终编写了一个自定义服务,该服务调用Facebook并填充UserProfile对象。
向项目中添加一个新的FBService.java类:
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版本。代之以你自己的。现在将此服务注入控制器,而不是调用:
UserProfile profile = connection.fetchUserProfile();调用新服务getProfile()方法,如下所示:
Profile profile = fbService.getProfile("me", connection.createData().getAccessToken());对我来说就像魔法一样。
Update:这里是完整的web控制器代码,它展示了如何为Facebook使用自定义服务,同时继续为Google的用户配置文件使用默认的服务:
@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
}
}发布于 2019-11-24 19:42:28
看起来facebook社交网站将不再更新。
无论如何,我不想花时间切换到另一个库。
我刚刚拿到了我需要的字段:
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中的字段:
/** 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";发布于 2019-10-29 21:27:19
EDIT#2:这个问题又发生在我身上。如果您想知道如何修改某个包并将其添加到maven中,请继续读下去,但是如果您只是想知道如何消除该错误(以及其他类似的错误涉及不同的属性),那么您应该只需遵循这个答案中的建议: https://stackoverflow.com/a/34133450/754988. --它比我的要好得多。
虽然阿科姆森的解决方案可能对某些人有效,但我依赖于其他服务(如谷歌登录)的抽象UserProfile,而他们的解决方案将打破这一点。
我发现一种不那么有侵略性的操作方法是转到ss-facebook的github,按照他们的指令中的前两行从源代码构建:
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"
};至
static final String[] PROFILE_FIELDS = {
"id", "about", "age_range", "birthday", "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>编辑:,我已经了解到这并不是在Maven中包含这样一个定制jar的最佳方法。这是一个小兔子洞,实际上,它在那里的工作,像其他罐子在你的pom。通过运行这些命令手动安装我制作的两个jars (3.0.1337是我为避免名称冲突而编写的版本-不确定是否有必要),我最终使它工作得更好.
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中声明的本地存储库,如下所示:
<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,只为其他人写下了一些简单的说明。你得冒着自己的风险继续执行这些指令。
此外,我刚刚检查了许可证,如果您确实做了此更改,请确保您遵循以下说明:
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and如果我漏掉了其他法律方面的东西,请发表意见让我知道。
https://stackoverflow.com/questions/57509883
复制相似问题