Abstract class and url mapping - spring

I have an abstract class
I try to have all generic method in this class.
I get issue about mapping.
public abstract class BaseControllerNew<T extends BaseEntity, R extends BaseDto, S extends BaseSearch> {
...
#GetMapping(value = "/{id}")
public R getById(#PathVariable("id") Integer id){
return baseServiceNew.getById(id);
}
#GetMapping(value = "/")
public Page<R> get(Pageable page){
return baseServiceNew.get(page);
}
....
}
#RequestMapping(value = "/rest/vehicules")
#RestController
public class VehiculesRestController extends BaseControllerNew<Vehicules, VehiculesDto, VehiculesSearch>{
private VehiculesServiceImpl vehiculesService;
#Autowired
public VehiculesRestController(final VehiculesServiceImpl vehiculesService) {
super(vehiculesService);
this.vehiculesService = vehiculesService;
}
I'm able to call
/rest/vehicules/1
but i get 404 for
/rest/vehicules

The problem is with your additional "/", this means your URL will be "/rest/vehicules/"
You only need #GetMapping
#GetMapping
public Page<R> get(Pageable page){
return baseServiceNew.get(page);
}

Related

Spring Boot #ConfigurationProperties

so I'm kinda new to Springboot and I'm trying to get the value from application.properties. I want to get multiple value from the application.properties and insert it into a list. At first, I tried to get the value from controller class and it works. Now I tried to get the value from a new class, but the value won't show up and it's showing an error because it says that it's null. Am i missing an annotation or did i do something wrong in the code? Below is my code.
application.properties:
example.name[0] = asdf
example.name[1] = qwer
List Value class:
#ConfigurationProperties(prefix = "example")
#Configuration
public class NameProperties {
private List<String> name;
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
What i tried in controller and worked:
#RestController
#CrossOrigin
#RequestMapping("/tes/**")
public class NameController {
#Autowired
NameProperties property = new NameProperties();
#GetMapping
public String tes() {
String name = property.getName().get(0);
System.out.println(name);
return name;
}
}
In the new class that doesn't work:
#Component
public class NameConfiguration {
#Autowired
NameProperties property = new NameProperties();
public void getName(int index) {
System.out.println(property.getName().get(0));
}
}
The code to test the new class in the controller:
#RestController
#CrossOrigin
#RequestMapping("/tes/**")
public class NameController {
NameConfiguration conf = new NameConfiguration();
#GetMapping
public String tes() {
conf.getName(0);
}
}
Is it because the value doesn't get injected when I call the class or what should I do? Appreciate any kind of help. Thanks!
Hello friend when you declare your class as a Spring Bean you shouldn't initialize the object yourself other the properties define in it will not be injected by Spring, so you should let spring help you with that, try these class below
NameProperties
#Component
#ConfigurationProperties(prefix = "example")
public class NameProperties {
private List<String> name;
public List<String> getName() {
return name;
}
public void setName(List<String> name) {
this.name = name;
}
}
NameConfiguration.java
#Component
public class NameConfiguration {
#Autowired
NameProperties property;
public void getName(int index) {
System.out.println(property.getName().get(0));
}
}

How refactor 2 restcontrollers almost identical?

I have 2 rest controllers which look the same:
File 1:
#RestController
#RequestMapping("/api/v1/foo")
#RequiredArgsConstructor
public class FooAPI {
private final ConfigService<Foo> service;
#GetMapping
(...)
File 2:
#RestController
#RequestMapping("/api/v1/bar")
#RequiredArgsConstructor
public class BarAPI {
private final ConfigService<Bar> service;
#GetMapping
(...)
Everything is the same, except the private final ConfigService<(Foo|Bar)> service;.
Is it possible to generalize a restcontroller class?
You can create abstract class that you can inherit from.
So you get something like:
Abstract class:
public abstract class AbstractAPI {
private final ConfigService<?> service;
public AbstractAPI(ConfigService<?> service){
this.service = service;
}
#GetMapping
(...)
File 1:
#RestController
#RequestMapping("/api/v1/foo")
public class FooAPI extends AbstractAPI {
public FooAPI (ConfigService<?> service) {
super(service);
}
}
File 2:
#RestController
#RequestMapping("/api/v1/bar")
public class BarAPI extends AbstractAPI {
public BarAPI (ConfigService<?> service) {
super(service);
}
}

SpringBoot 2.x #Inject DTO inside a Controller

I'm using SpringBoot 2.2.6 and I want to know if is it possibile to Inject a DTO inside my Controller. It is a DTO with info coming from various entities..
For example I have a service that build this DTO:
#Service
public class SomeService() {
public ThisDTO getThisDTO() {
Entity entity = repository.findBySome();
return transformToDto(entity);
}
}
Now suppose I have a Controller like this:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
}
I would like to use ThisDTO in all method of above Controller but I don't want to do something like:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
#Autowired
SomeService someService;
#GetMapping
public void method1() {
ThisDTO thisDTO = someService.getThisDTO();
}
#GetMapping
public void method2() {
ThisDTO thisDTO = someService.getThisDTO();
}
...
...
}
but I would like to know if there's a way to do something like:
#RestController
#RequestMapping(value = "/api/v1/Test")
public void TestController {
#Inject // or something else
ThisDTO thisDto;
...
...
}
Thank you all!

DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler

I am trying to design a rest api, and below is my controller code.
when i invoke http://localhost:8080/ the response is fine, but if i hit http://localhost:8080/api/ca it thorws javax.servlet.ServletException: No adapter for handler [...CaDetailController#48224381]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
#RestController("/api")
public class CaDetailController {
private static final Logger logger = LoggerFactory.getLogger(GetClassLoader.class.getClass());
#Autowired
CaService caService;
#RequestMapping(path = "/ca", method = RequestMethod.GET)
public #ResponseBody List<CaDetail> getCorporateActions() {
logger.info("CaDetailController.findAllCaDetails()");
return caService.findAllCaDetails();
}
#RequestMapping(path = "/ca/{caId}", method = RequestMethod.GET)
public #ResponseBody List<CaDetail> getCorporateActions(#PathParam("caId") long caId) {
logger.info("CaDetailController.getCorporateActions() : caId : " + caId);
return caService.findAllCaDetails();
}
}
Updated controller.
#RestController
#RequestMapping("/api/ca")
public class CaDetailController {
private static final Logger logger = LoggerFactory.getLogger(GetClassLoader.class.getClass());
#Autowired
CaService caService;
#GetMapping(path = "/")
public #ResponseBody List<CaDetail> getCorporateActions() {
logger.info("CaDetailController.findAllCaDetails()");
return caService.findAllCaDetails();
}
#GetMapping(path = "/{caId}")
public #ResponseBody List<CaDetail> getCorporateActions(#PathParam("caId") Long caId) {
logger.info("CaDetailController.getCorporateActions() : caId : " + caId);
return caService.findAllCaDetails();
}
}
For clarity, fix is:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/ca")
public class CaDetailController {
#GetMapping
public String healthcheck1() {
return "ok!";
}
#GetMapping(path = "health")
public String healthcheck2() {
return "ok again!";
}
}
You can call this endpoints using URL:
http://localhost:8080/api/ca and
http://localhost:8080/api/ca/health
(Assuming default Spring Boot Tomcat configuration).
Don't add ("/api") value to #RestController Annotation,
add it to #RequestMapping
#RestController
#RequestMapping("api/")
...
Try this
#RestController
#RequestMapping("/api")
public class CaDetailController {
instead of
#RestController("/api")
public class CaDetailController {

#Configurable not working on Subclass

Take the following general abstract class:
#Configurable
public abstract class TestEntityRoot {
public abstract String print();
}
And a subclass:
#Configurable
public class TestEntity extends TestEntityRoot{
private TestEntityService testEntityService;
#Autowired
public void setTestEntityService(TestEntityService testEntityService) {
this.testEntityService = testEntityService;
}
#Override
public String print() {
return testEntityService.print();
}
}
When call controller:
#RestController
public class TestEntityController {
#GetMapping(name = "/test")
public String print() {
TestEntity entity = new TestEntity();
return entity.print();
}
}
everything ok. But if call like this:
#RestController
public class TestEntityController {
#GetMapping(name = "/test")
public String print() {
TestEntityRoot entity = new TestEntity();
return entity.print();
}
}
i get null pointer. Is it possible that second example work?
In the second case you create manually the class rather than using spring's bean. Autowire the bean instead. See
#RestController
public class TestEntityController {
#Autowired
private TestEntity entity
#GetMapping(name = "/test")
public String print() {
return entity.print();
}
}

Resources