#java #spring #rest
#java #весна #rest
Вопрос:
Вот моя проблема :
У меня есть два класса: класс A содержит некоторые @Value("${param.username}")
и @Value("${param.password}")
, у меня есть функция, использующая эти 2 параметра, и я использую @GetMapping(path = "/functionA")
для запуска функции (эта функция представляет собой Post-запрос на сервер для аутентификации)
Имя пользователя и пароль включены application-contextual-values.properties
Когда я запускаю браузер localhost:8080/app/functionA
=> это работает!
У меня есть другой класс B, в другом пакете B я хочу вызвать первый класс A и использовать функцию для аутентификации. => У меня ошибка : Username must not be null
Это означает, что я не могу получить username
и password
которые хранятся в 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(); <====== this function is also in this class A
...
I'm doing a construction of params, to send on POST
return token;
}
Это AuthentificationModel
только то, что отправляется обратно после запроса POST (access_token, client_id, token_type)
Мой класс B :
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;
}
Мое приложение-contextual-values.properties :
param.username="kljkjsdf555sdf"
param.password="xxx222xxx"
Это потому, что мне нужно будет добавить конструктор в класс A с именем пользователя и паролем params? каков правильный способ заставить его работать в моем контексте?
Редактировать :
В классе A я добавил: @Controller
В классе B: я добавил @Authowired A objA
и нет new A();
Но теперь, имея новую ошибку : Cannot make a static reference to the non-static field objA
Это означает, что элементы класса A не являются статическими, и я использую objA как статический объект?
Ответ №1:
Используйте внедрение зависимостей и @Autowired вашего A
экземпляра B
и не создавайте новый экземпляр A
в своем B
классе.
Комментарии:
1. Я внес некоторые изменения в свой вопрос. Теперь после @ Autowired моего A в B появляется ошибка, предлагающая мне сделать @ Autowired статическим A
2. Почему
getRequestHeader
она должна быть статической?3. Класс
B
может быть другимComponent
с нестатическим методомgetRequestHeader
.4. Поместите
@Component
аннотацию надB
классом@Authowired
в любом другом месте, где вы хотите ее использовать.5. Работает! getRequestHeader не должен быть статическим да!
Ответ №2:
Spring может обрабатывать только объекты, которыми он управляет (создает чтение), включая разрешение / ввод данных, аннотированных, @Value
конечно.
Когда вы создаете экземпляр класса A
самостоятельно из класса B:
final A objA = new A();
Spring понятия не имеет, что этот класс должен быть обработан, фактически он даже не знает, что этот класс существует, следовательно, «значение» в не введено / установлено.
В общем, чтобы решить эту проблему, вам необходимо провести рефакторинг вашего кода. Непонятно, зачем вы создаете класс Controller (я предполагаю, что A
это контроллер, потому что его метод getClient
аннотируется @GetMapping
, что имеет смысл только в контроллерах).
Однако вам не нужно создавать экземпляр A, а скорее вводить его и убедиться, что оба A
и B
управляются Spring
Ответ №3:
Поскольку вы создаете экземпляр A, используя A objA = new A()
в классе B, spring не вводит никакого значения в класс A, поскольку это новый объект. Чтобы использовать внедрение свойств в классе A, вам необходимо использовать внедрение зависимостей и использовать компонент, уже созданный с использованием контекста приложения spring.
Я предполагаю, что класс 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(); <===== instance of my class A here
String token = objA.getClient().getAccessToken(); <==== getClient() is the funct that returns token on class A
Комментарии:
1. Спасибо, Такер, да, я забыл @Controller в классе A, но теперь, при автоматической настройке в классе B, у меня возникает ошибка: «Невозможно создать статическую ссылку на нестатическое поле objA», когда я делаю: @ Autowired static A objA; затем после компиляции у меня появляется ошибка 403, когда ядоступ к локальному хосту: 8080/app/functionA
2. @hek_ это связано с тем, что метод getRequestHeader является статическим методом, в то время как объект Autowired нестатичен.