英文:
Function called from another package cannot access to parameters
问题
以下是翻译好的内容:
这是我的问题:
我有两个类:类A包含一些@Value("${param.username}")
和@Value("${param.password}")
,我有一个使用这两个参数的函数,我使用@GetMapping(path = "/functionA")
来运行函数A(这个函数是向服务器发出的用于认证的Post请求)
用户名和密码存储在application-contextual-values.properties
中。
当我在浏览器上运行localhost:8080/app/functionA
时,它可以工作!
我有另一个类B,在另一个包B中,我想调用第一个类A并使用functionA进行认证。但是,我遇到了一个错误:Username must not be null
(用户名不能为空)。
这意味着我无法获取存储在application-contextual-values
文件中的用户名和密码。
这是类A的代码:
public class A {
@Value("${param.username}")
private String username;
@Value("${param.password}")
private String password;
@GetMapping(path = "functionA")
public AuthentificationModel getClient() {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(this.username, this.password);
String jwt = getJWT(); // 这个函数也在类A中
// ... 这里构造参数,以便进行POST请求
return token;
}
}
AuthentificationModel
只是在POST请求之后返回的内容(access_token、client_id、token_type)。
我的类B是:
import fr.ag2rlamondiale.ytb.rest.A; // 类A
public class B {
private static Map<String, String> getRequestHeader() {
Map<String, String> requestHeaders = new HashMap<>();
try {
final A objA = new A(); // 在这里创建了类A的实例
String token = objA.getClient().getAccessToken(); // getClient()是类A中返回token的函数
requestHeaders.put("Authorization", "Bearer " + token);
// ... 其他添加头部的操作
} catch (CommonException e) {
e.printStackTrace();
}
return requestHeaders;
}
}
我的application-contextual-values.properties
:
param.username="kljkjsdf555sdf"
param.password="xxx222xxx"
是因为我需要在类A中添加带有用户名和密码参数的构造函数吗?在我的情况下,使其正常工作的正确方法是什么?
编辑:
在类A中我添加了:@Controller
在类B中:我添加了@Autowired A objA
,并去掉了new A();
但是现在,出现了一个新错误:Cannot make a static reference to the non-static field objA
(无法在静态上下文中引用非静态字段objA)
这意味着类A中的元素是非静态的,而我在静态对象objA中使用了它?
英文:
Here is my problem :
I'm having two classes: class A contains some @Value("${param.username}")
and @Value("${param.password}")
, I have a function using those 2 params, and I a use @GetMapping(path = "/functionA")
to run the functionA (this function is a Post request to a server to authentificate)
Username and password are on application-contextual-values.properties
When I run on browser localhost:8080/app/functionA
=> it works !
I have another class B, on another package B, I want to call the first class A and use the fuctionA to authentificate. => I'm having an error : Username must not be null
It means that I cannot get username
and password
that are stored in application-contextual-values
file.
Here is my code of class A :
public class A {
@Value("${param.username}")
private String username;
@Value("${param.password}")
private String password;
@GetMapping(path = "functionA")
public AuthentificationModel getClient() {
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth(this.username, this.password);
String jwt = getJWT(); <====== this function is also in this class A
...
I'm doing a construction of params, to send on POST
return token;
}
The AuthentificationModel
is just what is sent back after the POST request (access_token, client_id, token_type)
My class B is :
import fr.ag2rlamondiale.ytb.rest.A; <==== class A
public class B {
private static Map<String, String> getRequestHeader() {
Map<String, String> requestHeaders = new HashMap<>();
try{
final A objA = new A(); <===== instance of my class A here
String token = objA.getClient().getAccessToken(); <==== getClient() is the funct that returns token on class A
requestHeaders.put("Authorization", "Bearer ", + token);
... many other put for header
} catch (CommonException e) {
e.printStackTrace();
}
return requestHeaders;
}
My application-contextual-values.properties :
param.username="kljkjsdf555sdf"
param.password="xxx222xxx"
Is it because I'll need to add constructor on class A with params username and password ? what is the proper way to make it work in my context ?
Edit :
In class A I added : @Controller
In class B : I added @Authowired A objA
and no new A();
But now, having a new error : Cannot make a static reference to the non-static field objA
Meaning that elements on class A are non-static and I'm using objA as a static object ?
答案1
得分: 0
使用依赖注入和 @Autowired 在 B
中注入您的 A
实例,不要在您的 B
类中创建 A
的新实例。
英文:
Use Dependency injection and @Autowired Your A
instance in B
and don't create new Instance of A
in your B
class.
答案2
得分: 0
Spring只能处理它管理的对象(即创建的对象),包括当然也包括使用@Value
注解注释的数据的解析/注入。
当您自己从类B创建类A
的实例时:
final A objA = new A();
Spring不知道必须处理这个类,实际上它甚至不知道这个类的存在,因此“value”没有被注入/设置。
通常来说,要解决这个问题,您需要重构您的代码。
目前不清楚您为什么要创建Controller类(我猜测A
是一个Controller,因为它的getClient
方法被@GetMapping
注解标注,而这只在Controller中有意义)。
然而,您不必创建A的实例,而是注入它,并确保A
和B
都由Spring管理。
英文:
Spring can process only the objects that it manages (read creates), including resolution / injection of data annotated with @Value
of course.
When you create the instance of class A
by yourself from class B:
final A objA = new A();
Spring has no idea that this class must be processed, in fact it doesn't even know that this class exists, hence the "value" in not injected/set.
In general to solve this, you need to refactor your code.
Its not clear why do you create the class of Controller (I assume that A
is a controller because it's method getClient
is annotated with @GetMapping
which makes sense only in controllers).
However, you don't have to create an instance of A, but rather inject it and make sure that both A
and B
are managed by Spring
答案3
得分: 0
由于您在类B中使用A objA = new A()
来创建A类的实例,Spring不会在类A中注入任何值,因为它是一个新对象。要在类A中使用属性注入,您需要使用依赖注入,并使用已经在Spring应用程序上下文中实例化的A类的bean。
我假设A类带有@Controller
注解。
@Controller
public class A {
并且在类B中像下面这样使用自动装配来注入A类的实例:
public class B {
@Autowired
A objA;
private static Map<String, String> getRequestHeader() {
Map<String, String> requestHeaders = new HashMap<>();
try{
//final A objA = new A(); <===== 在此处实例化了我的A类的实例
String token = objA.getClient().getAccessToken(); //<==== getClient()是在类A中返回令牌的函数
英文:
Since you are creating instance of A using A objA = new A()
in class B, spring does not inject any value in class A as it is new object. To use property injection in class A, you need to use dependency injection and use bean of A already instantiated using spring application context.
I assume Class A is annotated with @Controller.
@Controller
public class A {
and use autowiring in class B like below to inject instance of A
public class B {
@Autowired
A objA;
private static Map<String, String> getRequestHeader() {
Map<String, String> requestHeaders = new HashMap<>();
try{
//final A objA = new A(); <===== instance of my class A here
String token = objA.getClient().getAccessToken(); <==== getClient() is the funct that returns token on class A
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论