Как решить "Ошибка при извлечении ответа для типа [class com. *" В Spring Boot?
Возможно, вы захотите перейти к моему ОБНОВЛЕНИЮ 2 ниже
У меня есть RestController, который работает, потому что, когда я обращаюсь к нему напрямую из браузера, он возвращает ответ JSON. Однако когда я отправляю запрос от Сервиса в другом ограниченном контексте, я получаю сообщение об ошибке:
{"timestamp":1579095291446,"message":"Error while extracting response for type
[class com.path.to.contexttwo.client.dto.WorkerDetails] and content type [application/json]; nested exception is
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error:
Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false');
nested exception is com.fasterxml.jackson.core.JsonParseException:
Unexpected character ('<' (code 60)):
expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (PushbackInputStream);
line: 1, column: 2]","details":"uri=/context-two/register-new"}
Вот мой код:
RestController
package com.path.to.contextone.aplication.presentation;
@RestController
@RequestMapping(path = "/iacess", produces = "application/json")
@CrossOrigin(origins = "*")
public class IAccessRestController {
UserRepository userRepo;
IAcessService iaccessService;
EntityLinks entityLinks;
@Autowired
public IAccessRestController(
UserRepository userRepo,
IAcessService iaccessService,
EntityLinks entityLinks) {
this.userRepo = userRepo;
this.iaccessService= iaccessService;
this.entityLinks = entityLinks;
}
@GetMapping("/get-worker-details/{userName}")
public WorkerDetails getWorkerDetails(@PathVariable String userName) {
User user = userRepo.findByUsername(userName);
WorkerDetails workerDetails = new WorkerDetails();
workerDetails.setUserId(userId);
workerDetails.setGender(user.gender());
workerDetails.setFirstName(user.getFirstName());
workerDetails.setLastName(user.getLastName());
workerDetails.setPhoneNumber(user.getPhoneNumber());
if (workerDetails != null) {
return workerDetails;
}
return null;
}
}
RestClient
package com.path.to.contexttwo.client;
// imports omitted, as well as other code
@Service
public class IAcessRestClientImpl implements IAcessRestClient {
private final RestTemplate restTemplate;
@Autowired
public IAcessRestClientImpl(
final RestTemplate restTemplate
) {
this.restTemplate = restTemplate;
}
@Override
public WorkerDetails getWorkerDetailsByName(final String userName) throws URISyntaxException {
Map<String,String> urlVariables = new HashMap<>();
urlVariables.put("userName", userName);
return restTemplate.getForObject(
"http://localhost:8080/iacess/get-worker-details/{userName}",
WorkerDetails.class,
urlVariables
);
}
}
Конфиг
package com.path.to.contexttwo.configuration;
@Configuration
@EnableWebMvc
public class RestClientConfig {
@Bean
public RestTemplate restTemplate() {
final RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.APPLICATION_JSON);
converter.setSupportedMediaTypes(mediaTypes);
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);
restTemplate.getInterceptors().add(new JsonInterceptor());
return restTemplate;
}
}
WorkerDetails
package com.path.to.contexttwo.client.dto;
import java.io.Serializable;
import java.util.Objects;
public class WorkerDetails implements Serializable {
private long userId;
private String gender;
private String firstName;
private String lastName;
private String phoneNumber;
public WorkerDetails() {
this.userId = -1;
this.gender = null;
this.firstName = null;
this.lastName = null;
this.phoneNumber = null;
}
// omitted all args constructor, getters, setters, equals, hascode, toString for simplicity
}
WorkerDetails также существует в пакете com.path.to.contextone.ohs_pl;
3 дня пробовал читать и отлаживать, безрезультатно. Отладчик, кажется, показывает, что ошибка возникает, когда RestTemplate анализирует WorkerDetails.class.
Я также пробовал использовать ComponentScan во всех классах конфигурации, потому что файлы находятся в отдельных пакетах (ограниченные контексты), но безуспешно.
Я мог бы просто использовать UserDetailsRepository из класса, который вызывает IAcessRestClient для получения WorkerDetails, но это сделало бы два разных ограниченных контекста зависимыми от одной и той же схемы базы данных.
Любая помощь будет очень признательна. Я могу разместить дополнительный код по запросу.
заранее спасибо
ОБНОВЛЕНИЕ@S B запрашивает параметры ввода. вот класс, который отправляет параметры:
Компания ServiceImpl
package com.path.to.contexttwo.domain.services;
// imports
@Service
public class CompanyServiceImpl implements CompanyService {
private CompanyRepository companyRepository;
private CompanyWorkerRepositoery companyWorkerRepositoery;
private WorkerDetailsClient workerDetailsClient;
private WebApplicationContext applicationContext;
@Autowired
CompanyServiceImpl (
CompanyRepository companyRepository,
CompanyWorkerRepositoery companyWorkerRepositoery,
WorkerDetailsClient workerDetailsClient,
WebApplicationContext applicationContext
) {
this.companyRepository = companyRepository;
this.companyWorkerRepositoery = companyWorkerRepositoery;
this.workerDetailsClient = workerDetailsClient;
this.applicationContext = applicationContext;
}
@Transactional
public Company criateCompany(CompanyDTO dto) throws URISyntaxException {
if (dto.getLegalyAuthorized() == true && dto.getTerms() == true) {
Company company = new Company(
dto.getCompanyName(),
dto.getStateId()
);
company = CompanyRepository.save(company);
// when saving the company, we also need some details from the current logged in user which can be
// retrieved from the idendity and access bounded context. We need those details to be saved in this context
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();
WorkerDetails workerDetails = WorkerDetailsClient.getWorkerDetailsByName(
name
);
// ... we can't reach the rest of the code anyway, so we omitted
}
}
И вот ответ, который я получаю при прямом доступе к RestController:
{"userId":127,"gender":"M","firstName":"Primeiro","lastName":"Último","phoneNumber":"922222222"}
ОБНОВЛЕНИЕ 2
Закомментировал.anyRequest(). Authenticated(), и все заработало нормально! Итак, все это время это имеет отношение к Spring Security. Какая жалость. Теперь попробуем заставить все работать с включенной безопасностью. Я получал HTML как ответ из-за перенаправления на страницу входа. Правильно реализована аутентификация (запрос токена с базовой аутентификацией), и все работает хорошо.
Спасибо вам всем!
1 ответ
Пытаться:
return restTemplate.getForObject(
"http://localhost:8080/iacess/get-worker-details/" + userName,
WorkerDetails.class);