Untitled

 avatar
unknown
java
13 days ago
7.1 kB
2
Indexable
Ваш код имеет несколько моментов, которые можно улучшить и исправить для повышения его качества и работоспособности. Давайте рассмотрим основные аспекты:

1. Реализация HhApiClientImpl
Ваш метод fetchVacancies возвращает null. Вам нужно реализовать логику для получения данных с сайта hh.ru. Вы можете использовать RestTemplate или WebClient для выполнения HTTP-запросов.

2. Обработка команд в CommandController
Ваш метод extractCommandName предполагает, что команда всегда будет первым словом в сообщении. Это может быть не всегда верно. Также стоит добавить обработку исключений и логирование.

3. Сущность Vacancy
Поле id в сущности Vacancy имеет тип String, но обычно идентификаторы в базе данных имеют числовой тип. Также стоит добавить аннотацию @Entity к классу Vacancy.

4. Обработка ошибок
Добавьте обработку ошибок в различных частях вашего кода, например, при работе с базой данных или при получении данных с внешнего API.

5. Конфигурация
В вашем properties.yaml есть опечатка: name: HHMonitorBot должно быть name: HHMonitorBot. Также стоит добавить конфигурацию для логирования.

6. Зависимости
Убедитесь, что все необходимые зависимости добавлены в build.gradle. Например, для работы с JSON вы можете использовать Jackson, который уже добавлен.

7. Тестирование
Добавьте тесты для ваших сервисов и контроллеров. Это поможет убедиться, что ваш код работает корректно.

Пример рефакторинга
Реализация HhApiClientImpl
java
@Service
public class HhApiClientImpl implements ApiClient {
    private final RestTemplate restTemplate;
    private final String apiUrl;

    @Autowired
    public HhApiClientImpl(@Value("${hh.api.url}") String apiUrl) {
        this.restTemplate = new RestTemplate();
        this.apiUrl = apiUrl;
    }

    @Override
    public List<Vacancy> fetchVacancies(SearchFilter filter) {
        try {
            String url = buildUrl(filter);
            ResponseEntity<VacancyResponse> response = restTemplate.getForEntity(url, VacancyResponse.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                return response.getBody().getItems();
            } else {
                throw new ApiClientException("Failed to fetch vacancies: " + response.getStatusCode());
            }
        } catch (Exception e) {
            throw new ApiClientException("Error fetching vacancies", e);
        }
    }

    private String buildUrl(SearchFilter filter) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(apiUrl)
                .queryParam("text", filter.getQuery())
                .queryParam("area", filter.getArea())
                .queryParam("experience", filter.getExperience());
        return builder.toUriString();
    }
}

class VacancyResponse {
    private List<Vacancy> items;

    public List<Vacancy> getItems() {
        return items;
    }

    public void setItems(List<Vacancy> items) {
        this.items = items;
    }
}
Обработка команд в CommandController
java
@Controller
public class CommandController {
    private final Map<String, CommandHandler> handlers = new HashMap<>();

    public CommandController(List<CommandHandler> handlers) {
        handlers.forEach(handler -> this.handlers.put(handler.getCommandName(), handler));
    }

    public void processCommand(Message message, TelegramBot bot) {
        String commandName = extractCommandName(message);
        CommandHandler handler = this.handlers.get(commandName);
        if (handler != null) {
            handler.handle(message, bot);
        } else {
            bot.sendMessage(new SendMessage(message.getChatId(), "Unknown command: " + commandName));
        }
    }

    private String extractCommandName(Message message) {
        String text = message.getText();
        if (text != null && text.startsWith("/")) {
            return text.split(" ")[0].substring(1);
        }
        return "";
    }
}
Сущность Vacancy
java
@Entity
public class Vacancy {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String url;
    private LocalDateTime publishedAt;

    // getters and setters
}
Обработка ошибок
Добавьте глобальный обработчик ошибок:

java
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ApiClientException.class)
    public ResponseEntity<String> handleApiClientException(ApiClientException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
    }

    @ExceptionHandler(InvalidFilterException.class)
    public ResponseEntity<String> handleInvalidFilterException(InvalidFilterException e) {
        return ResponseEntity.badRequest().body(e.getMessage());
    }
}
Конфигурация
Добавьте конфигурацию для логирования в application.properties:

properties
logging.level.root=INFO
logging.level.ru.dmt100.hhmonitorbotapplication=DEBUG
Тестирование
Добавьте тесты для ваших сервисов и контроллеров. Например, тест для HhApiClientImpl:

java
@SpringBootTest
public class HhApiClientImplTest {
    @Autowired
    private HhApiClientImpl hhApiClient;

    @Test
    public void testFetchVacancies() {
        SearchFilter filter = new SearchFilter();
        filter.setQuery("Java");
        filter.setArea("1");
        filter.setExperience("noExperience");

        List<Vacancy> vacancies = hhApiClient.fetchVacancies(filter);
        assertNotNull(vacancies);
        assertFalse(vacancies.isEmpty());
    }
}
Это лишь базовый пример рефакторинга. В зависимости от ваших требований и архитектуры проекта, могут потребоваться дополнительные изменения.
Leave a Comment