how to split resource in spring boot - spring-boot

In Jersey we can do something like
#Path("/")
public class TopResource{
#GET
public Response getTop() { ... }
#Path("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
public class ContentResource {
#GET
public Response getContent() { ... }
}
so,
https://<host> will invoke getTop()
https://<host>/content will invoke getContent()
is there any equivalent in Spring?
I tried
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
#RequestMapping("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
#RestController
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}
only top resource works. content would return 404 Not Found.
Not sure how to do this in Spring Boot.
Tried replacing #RestController with #Resource and #Controller for content, but still got 404 Not Found.

There is no option to retun a whole class, please use the Annotation #RequestMapping on top of your content class to split them up.
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
}
#RestController
#RequestMapping("content")
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}

Related

Spring Boot - #RestController annotation gets picked up, but when replaced with #Controller annotation, it stops working

Here is a dummy project for the same :-
BlogApplication.java
#SpringBootApplication
#RestController
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
#GetMapping("/hello")
public String hello(#RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello %s!", name);
}
}
HtmlController.java
#Controller //does not work
OR
#RestController //works
public class HtmlController {
#GetMapping("/getHtmlFile")
public String getHtmlFile() {
return "Bit Torrent Brief";
}
}
Why is it that #RestController is able to map getHtmlFile but #Controller returns 404 when /getHtmlFile is hit?
#RestController is the combination of #Controller and #ResponseBody.
when you use #Controller, you should write #ResponseBody before your method return type
#Controller
public class HtmlController {
#GetMapping("/getHtmlFile")
public #ResponseBody String getHtmlFile() {
return "Bit Torrent Brief";
}
}
This works.

Spring Boot Application ,JPA,

I have created a small application using the spring boot framework. I have created a Rest Controler class.
and deploy it on tomcat, but I am getting 404 error i.e
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
#RestController
#RequestMapping("students")
public class StudentController {
#Autowired
StudentRepository repository;
#GetMapping
public List<Student> getAllStudents() {
return (List<Student>) repository.findAll();
}
#PostMapping
public String createStudent() {
return "created";
}
#PutMapping
public String updateStudent() {
return "updated";
}
#DeleteMapping
public String deleteStudent() {
return "deleted";
}
}
You are missing slash in annotation, it should look like this
#RestController
#RequestMapping("/students")
public class StudentController {
...
}

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!

In Spring how to send enum as response in controller

I have Enum Class. I Need to send a Enum class Response from the Spring controller.
I am not able understand how to sent class as Response in spring controller. Please help me for that.
You can add anything which Jackson can de-serialize in a reponse
#RestController
public class HelloController {
#RequestMapping("/monday")
public ResponseEntity<DayOfWeek> monday() {
return new ResponseEntity<DayOfWeek>(DayOfWeek.MONDAY, HttpStatus.OK);
}
#RequestMapping("/days")
public ResponseEntity<List<DayOfWeek>> days() {
return new ResponseEntity<List<DayOfWeek>>(Arrays.asList(DayOfWeek.values()), HttpStatus.OK);
}
}
You can prove this to yourself with the following test, just do the Jacskon de-serialization manually
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class HelloControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void monday() throws Exception {
String json = new ObjectMapper().writeValueAsString(DayOfWeek.MONDAY);
mvc.perform(MockMvcRequestBuilders.get("/monday").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(content().string(equalTo(json)));
}
#Test
public void days() throws Exception {
String json = new ObjectMapper().writeValueAsString(Arrays.asList(DayOfWeek.values()));
mvc.perform(MockMvcRequestBuilders.get("/days").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(content().string(equalTo(json)));
}
}
If you wanna return all enum values than try something like this:
#GetMapping("enum")
public List<MyEnum> paymentMethods() {
return Arrays.asList(MyEnum.values());
}
public enum MyEnum {
FIRST, SECOND, THIRD;
}

Returing Hystrix AsyncResult from Spring Boot Controller

I have the following Spring Boot controller:
#Controller
public class TestController {
#Autowired
private TestService service;
#GetMapping(path="/hello")
public ResponseEntity<String> handleGet() {
return service.getResponse();
}
#GetMapping(path="/hello/hystrix")
public Future<ResponseEntity<String>> handleGetAsync() {
return service.getResponseAsync();
}
#GetMapping(path="/hello/cf")
public Future<ResponseEntity<String>> handleGetCF() {
return service.getResponseCF();
}
}
and service:
#Service
public class TestService {
#HystrixCommand
public ResponseEntity<String> getResponse() {
ResponseEntity<String> response = ResponseEntity.status(HttpStatus.OK).body("Hello");
return response;
}
#HystrixCommand
public Future<ResponseEntity<String>> getResponseAsync() {
return new AsyncResult<ResponseEntity<String>>() {
#Override
public ResponseEntity<String> invoke() {
return getResponse();
}
};
}
public Future<ResponseEntity<String>> getResponseCF() {
return CompletableFuture.supplyAsync(() -> getResponse());
}
}
and application:
#EnableHystrix
#SpringBootApplication
#EnableAsync
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
When I hit the /hello/cf endpoint, I get a response "Hello"
When I hit the /hello/hystrix endpoint, I get a 404 error.
Am I able to return an AsyncResult from a controller in this manner? If so, what am I doing wrong?
Thanks.
Your service class needs to return a CompletableFuture.
Also, unless you are using AspectJ, the circuit breaker will not work if the method with #HystrixCommand is called from within the same class.

Resources