My class Rest doesn't invoke my other class
#CrossOrigin(allowedHeaders = "*")
#RestController
public class PhoneRest {
#Autowired
private TradePhoneService service;
#CrossOrigin(origins = {"http://localhost:4200","http://localhost:8081"})
#PostMapping(value = "/listarRamaisDiponiveis", produces = "application/json")
public ResponseEntity <List<TpbPrvtRecPhoneExtVO>> listarRamaisDiponiveis() {
List<TpbPrvtRecPhoneExtVO> list = new ArrayList<>();
try {
list =service.listarRamaisDiponiveis(); // here java.lang.classcastexception
About interface TradePhoneService:
public interface TradePhoneService {
public List<TpbPrvtRecPhoneExtVO> listarRamaisDiponiveis();
About class TpbPrvtRecPhoneExtVO:
public class TpbPrvtRecPhoneExtVO extends BaseVO implements Serializable{
And about class TradePhoneServiceImpl that implements TradePhoneService:
#Transactional(rollbackOn=Exception.class)
#Service
public class TradePhoneServiceImpl implements TradePhoneService {
#Autowired
private TradePhoneDAO dao;
public List<TpbPrvtRecPhoneExtVO> listarRamaisDiponiveis() {
return listBeansToVos(dao.listarRamaisDiponiveis());
}
Where is the problem?
Thanks
Marcos Vizine
Related
I created a custom exception hanle in a separate module and wanted to use the same GlobalExceptionHandle class in another module. Although an exception appears on the console, but no custom exception appears on the postman. What could be the reason for this? pls help me
GlobalExceptionHandle.java
#RestControllerAdvice
#Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandle extends ResponseEntityExceptionHandler {
#ExceptionHandler(NotFoundException.class)
public ResponseEntity<CustomExceptionResponseDto> handle(NotFoundException exception) {
return new ResponseEntity<CustomExceptionResponseDto>(
CustomExceptionResponseDto.builder()
.errorCode(HttpStatus.NOT_FOUND)
.message(exception.getMessage())
.status(HttpStatus.NOT_FOUND.value())
.timestamp(LocalDateTime.now())
.build(), HttpStatus.NOT_FOUND
);
}
#ExceptionHandler(InvalidStateException.class)
public ResponseEntity<CustomExceptionResponseDto> handle(InvalidStateException exception) {
return new ResponseEntity<CustomExceptionResponseDto>(
CustomExceptionResponseDto.builder()
.errorCode(HttpStatus.BAD_REQUEST)
.message(exception.getMessage())
.status(HttpStatus.BAD_REQUEST.value())
.timestamp(LocalDateTime.now())
.build(), HttpStatus.BAD_REQUEST
);
}
}
UserController.java
#RestController
#RequestMapping("/user")
#RequiredArgsConstructor
public class UserController {
private final UserService userService;
#PostMapping
public ResponseEntity<UserResponseDto> save(#RequestBody UserRequestDto userRequestDto) {
return ResponseEntity.ok(userService.save(userRequestDto));
}
}
UserServiceImpl.java
#Service
#RequiredArgsConstructor
#Slf4j
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
#Override
public UserResponseDto save(UserRequestDto userRequestDto) {
log.info("User request dto: " + userRequestDto);
userRepository.findUserByEmail(userRequestDto.getEmail()).ifPresent((user) -> {
throw new EmailAlreadyUseException(user.getEmail());
});
var user = userMapper.userRequestDtoToUser(userRequestDto);
user.setPassword(bCryptPasswordEncoder.encode(userRequestDto.getPassword()));
return userMapper.userToUserResponseDto(userRepository.save(user));
}
}
InvalidStateException.java
public class InvalidStateException extends RuntimeException {
private static final long serialVersionUID = 1L;
public InvalidStateException(String message) {
super(message);
}
}
EmailAlreadyUseException.java
public class EmailAlreadyUseException extends InvalidStateException {
public EmailAlreadyUseException(String email) {
super(email+" already registered,try different email");
}
}
I see you're throwing throw new EmailAlreadyUseException(user.getEmail()); but you handle #ExceptionHandler(InvalidStateException.class) try to change into#ExceptionHandler(EmailAlreadyUseException.class) and check it out.
I'm trying to write a really basic application using Spring-Boot. The only thing I'm currently trying is to get some information out of a SQL Server database.
Application.java
#SpringBootApplication(scanBasePackageClasses = { MainView.class, Application.class })
#EnableJpaRepositories(basePackageClasses = CustomerRepository.class)
#EntityScan(basePackageClasses = Customer.class)
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
Customerrepository.java
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer>
{
}
CustomerController.java
#Controller
#RequestMapping(path = "/customer")
public class CustomerController {
#Autowired
private CustomerRepository customerRepository;
#GetMapping(path = "/all")
public #ResponseBody Iterable<Customer> getAllCustomers() {
return customerRepository.findAll();
}
}
CustomersView.java
#Tag("customers-view")
#HtmlImport("src/views/customers/customers-view.html")
#Route(value = ApplicationConst.PAGE_CUSTOMERS, layout = MainView.class)
#PageTitle(ApplicationConst.TITLE_CUSTOMERS)
public class CustomersView extends PolymerTemplate<TemplateModel> {
#Autowired
CustomerRepository customerRepository;
public CustomersView() {
customerRepository.findAll();
}
}
Going to http://localhost:8080/customer returns every customer in my database just fine.
But when I try to find all the customers in my CustomersView.java, the autowired CustomerRepository returns a nullpointerexception.
Is somebody able to point me in the right direction?
Try to #Autowire the Repository in the constructor like this:
#Tag("customers-view")
#HtmlImport("src/views/customers/customers-view.html")
#Route(value = ApplicationConst.PAGE_CUSTOMERS, layout = MainView.class)
#PageTitle(ApplicationConst.TITLE_CUSTOMERS)
public class CustomersView extends PolymerTemplate<TemplateModel> {
CustomerRepository customerRepository;
#Autowired
public CustomersView(CustomerRepository customerRepository) {
this.costumerRepository = customerRepository;
this.customerRepository.findAll();
}
}
This happens because all #autowired-attributes are inserted after the constructor gets completed. If you want to inject the #autowired-attributes at constructor-time, you have to use the method above.
I have a controller for REST services for a particular type of resources (Symptoms) that looks like this:
#RequestMapping(value = "/symptom", produces = "application/json")
public class SymtomController {
#Autowired
private SymptomRepository repository;
#Autowired
private SymptomResourceAssembler assembler;
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<SymptomResource>> findAllSymptoms() {
List<SymptomEntity> symptoms = repository.findAll();
return new ResponseEntity<>(assembler.toResourceCollection(symptoms), HttpStatus.OK);
}
...
}
But, as I need to produce more controllers, for other resources, I would like to generate an abstract class and subclasses
public class AbstractController<Entity extends AbstractEntity, Resource extends GenericResource {
// repository and assembler somehow transferred from subclasses
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Resource>> findAllResources() {
List<Entity> entities = repository.findAll();
return new ResponseEntity<>(assembler.toResourceCollection(entities), HttpStatus.OK);
}
...
}
#RequestMapping(value = "/symptom", produces = "application/json")
public class SymtomController extends ResourceController<SymptomEntity, SymptomResource>{
#Autowired
private SymptomRepository repository;
#Autowired
private SymptomResourceAssembler assembler;
...
}
But I do not know it is possible, somehow, to transfer the autowired elements in the subclasses to the abstract class in a nice way (i.e. not sending them as parameters on each function call).
Any ideas?
Move the dependencies to the parent.
abstract class Parent {
#Autowired
protected MyRepository repo;
#PostConstruct
public void initialize(){
System.out.println("Parent init");
Assert.notNull(repo, "repo must not be null");
}
}
#Component
class Child extends Parent {
#PostConstruct
public void init(){
System.out.println("Child init");
Assert.notNull(repo, "repo must not be null");
}
}
I'm trying to create an abstract class that performs the common REST operations that are required, but can't work out if what I'm trying to do is possible. I've tried a number of approaches, but have stripped the code below right back to how it should work in my head
Classes updated as per suggestions below. Problem now is that the constructor in the concrete class isn't valid, as CustomerRepository isn't assignable to JpaRepository, though it extends that interface.
AbstractRestController
public abstract class AbstractRestController<T> {
private final JpaRepository<T, Serializable> repository;
public AbstractRestController(JpaRepository<T, Serializable> repository) {
this.repository = repository;
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<JsonResponseBody<T>> getOne(#PathVariable Long id) {
T restObj = repository.findOne(id);
JsonResponseBody<T> response = new JsonResponseBody<>(ResponseStatus.SUCCESS, restObj);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(response);
}
protected JpaRepository<T, Serializable> getRepository() {
return repository;
}
}
CustomerController
#RestController
#RequestMapping(value = "/api/v1/customer")
public class CustomerController extends AbstractRestController<Customer> {
#Autowired
public CustomerController(CustomerRepository repository){
super(repository);
}
}
CustomerRepository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}
Indeed, as #dino-tw mentions, you are trying to instantiate an abstract class with an undefined dependency. You can absolutely have an abstract controller class, and even define request handling methods that will be inherited by all subclasses. Try this instead:
public abstract class AbstractRestController<T, ID extends Serializable> {
private final JpaRepository<T, ID> repository;
public AbstractRestController(JpaRepository<T, ID> repository){
this.repository = repository;
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<JsonResponseBody<T>> getOne(#PathVariable ID id) {
T restObj = repository.findOne(id);
JsonResponseBody<T> response = new JsonResponseBody<>(ResponseStatus.SUCCESS, restObj);
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8).body(response);
}
protected JpaRepository<T, ID> getRepository(){ return repository; }
}
#RestController
#RequestMapping(value = "/api/v1/customer")
public class CustomerController extends AbstractRestController<Customer, Long> {
#Autowired
public CustomerController(CustomerRepository repository){
super(repository);
}
}
I'm trying to create a simple web-page, which is displaying the data, received from web-service
#Service
#Transactional
public class TopicService {
#Autowired
private TopicRepository topicRepository;
public int saveTopic(Topic topic){
return topicRepository.save(topic).getId();
}
public Iterable<Topic> findAllTopics(){
return topicRepository.findAll();
}
public Topic findTopicByID(Long id){
return topicRepository.findOne(id);
}
public List<Topic> findTopicsByTag(Tag tag){
return topicRepository.findAllByTopicTag(tag);
}
}
topic repository extends CRUD-repository
#Repository
public interface TopicRepository extends CrudRepository<Topic, Long>
{
List<Topic> findAllByTopicTag(Tag currentTag);
}
the controller invokes a service in the following way
#Controller
public class HomeController {
private TopicService service;
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView home(Locale locale, Model model)
{
Iterable<Topic> listTopic = service.findAllTopics();
return new ModelAndView("home", "model", listTopic);
}
}
this string
Iterable listTopic = service.findAllTopics();
throws null-pointer exception. I guess, because the service isn't initialized. How could I perform correct initialization of the service?
You need to autowire the TopicService in HomeController:
#Controller
public class HomeController {
#Aurowired
private TopicService service;