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;
Related
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
I have two controllers (UserController and ClientController), both of the controllers are located on the same package (com.myapp.controllers.identity), and my main application file located on the parent package (com.myapp).
I create the ClientController first and it works fine. Later on, I create the UserController. When I called the UserController, it always returns 404.
Here is the snippet of my controllers' files and main application file
Application.java
package com.myapp;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ClientController.java
package com.myapp.controllers.identity;
#RestController
#RequestMapping(value = "/api/identity")
#Validated
public class ClientController {
#GetMapping(value = "/clients/{clientId}")
public ResponseEntity<?> getClientByClientId(#PathVariable("clientId") String clientId) {
}
}
UserController.java
package com.myapp.controllers.identity;
#RestController(value = "UserController")
#RequestMapping(value = "/api/identity")
#Validated
public class UserController {
public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());
#Autowired
private UserService userService;
#GetMapping(value = "/users/client/:clientId")
public ResponseEntity<?> getAllUsersByClientId(#PathVariable String clientId)
{
}
}
Can anybody help me solve it?
There is one simple problem in your userControler, and that is #GetMapping(value = "/users/client/:clientId") your format of capturing parameter
this kind of parameter is not supported in spring as #chrylis -on strike- mentioned
package com.myapp.controllers.identity;
#RestController(value = "UserController")
#RequestMapping(value = "/api/identity")
#Validated
public class UserController {
public static final Logger logger = LoggerFactory.getLogger(UserController.class.getName());
#Autowired
private UserService userService;
#GetMapping(value = "/{clientId}")
public ResponseEntity<?> getAllUsersByClientId(#PathVariable String clientId)
{
}
}
When I call another Service (User-service) from one service (API-gateway) Using Feign Client, I'm getting an Error
There are two services
User-service
API-gateway
In my API-gateway
FeignClient
#FeignClient(contextId = "user-by-email",name = "user-service")
#Service
public interface UserByEmail {
#RequestMapping(value = "/email/{email}", consumes= MediaType.APPLICATION_JSON_VALUE)
User findByEmail(#PathVariable("email") String email);
}
Controller
#RequestMapping("/test")
public class TestController {
#Autowired
private UserByEmail userByEmail;
#GetMapping(value = "/{email:.+}")
public ResponseEntity testUser(#PathVariable("email") String username) {
return ResponseEntity.ok(userByEmail.findByEmail(username));
}
}
I need to call the following (User-service)
Controller
#EnableFeignClients
#RestController
public class UserController extends BaseController<User> {
#Autowired
private UserService userService;
#PostConstruct
public void binder() {
init(this.userService);
}
#GetMapping(value = "/email/{email}")
public ResponseEntity findByEmail(#PathVariable("email") String email) {
return ResponseEntity.ok(userService.findByEmail(email));
}
}
Repository
#Override
public User findByEmail(String email) {
Query query = new Query(Criteria.where("email").is(email).and("status").is(1));
return mongoOperations.findOne(query, User.class);
}
Service
#Override
public User findByEmail(String email) {
return userDao.findByEmail(email);
}
The Error I'm getting is ..
<Map>
<timestamp>1583924335777</timestamp>
<status>406</status>
<error>Not Acceptable</error>
<message>Could not find acceptable representation</message>
<trace>org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:246)
Can anyone please explain What is wrong with my code, And give your valuable solutions
(Basically I need to create Security in API-gateway, in order to control the access of other services)
Try Implementing Feign client as below:
#FeignClient(name = "user-service")
public interface UserByEmail {
#RequestMapping(method = RequestMethod.GET, value = "/email/{email}", consumes = "application/json")
User findByEmail(#PathVariable("email") String email);
}
also make sure the Fields passed over JSON matchers User POJO.
I've got the solution to my Question
FeignClient
#FeignClient(contextId = "user-by-email",name = "user-service")
#Service
public interface UserByEmail {
#RequestMapping(value = "/email/{email}", consumes= MediaType.APPLICATION_JSON_VALUE)
User findByEmail(#RequestParam("email") String email);
}
Controller
#RequestMapping("/test")
public class TestController {
#Autowired
private UserByEmail userByEmail;
#GetMapping(value = "/{email}")
public ResponseEntity testUser(#RequestParam("email") String username) {
return ResponseEntity.ok(userByEmail.findByEmail(username));
}
}
In User-service
Controller
#EnableFeignClients
#RestController
public class UserController extends BaseController<User> {
#Autowired
private UserService userService;
#PostConstruct
public void binder() {
init(this.userService);
}
#GetMapping(value = "/email/{email}")
public ResponseEntity findByEmail(#RequestParam("email") String email) {
return ResponseEntity.ok(userService.findByEmail(email));
}
}
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 want to call all the request mapping method(which has #Resource injection) before the server starts. How I can do this?
#Controller
public class ServiceController {
#Resource(name="userService")
private IUserService userService;
#RequestMapping("/getAllCountry")
public String getAllCountry() {
return userService.getAllCountry();
}
#RequestMapping("/getAllStates")
public String getAllStates() {
return userService.getStates();
}
#PostConstruct
public void cacheData(){
cache.put("ALL_COUNTRY_DATA", getAllCountry());
cache.put("ALL_STATE_DATA", getAllStates());
}
}
The above code fails and give me IllegalStateException. What is the best way to call the request mapping methods before the server is up and populate the cache.
Try using ApplicationListener in conjunction with ContextRefreshedEvent:
#Controller
public class ServiceController implements ApplicationListener<ContextRefreshedEvent> {
private static final Map<String, String> cache = new HashMap<>();
#Resource(name = "userService")
private IUserService userService;
#RequestMapping("/getAllCountry")
public String getAllCountry() {
return userService.getAllCountry();
}
#RequestMapping("/getAllStates")
public String getAllStates() {
return userService.getStates();
}
public void cacheData() {
cache.put("ALL_COUNTRY_DATA", getAllCountry());
cache.put("ALL_STATE_DATA", getAllStates());
}
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
cacheData();
}
}