I have a spring boot api. My problem is how do I actually create a page in my app?
I created a page in /resources/static/templates/index.html
and when I get to /api/lol I just see a string saying index and not the page.
How do I do this?
#RequestMapping("/api")
#RestController
public class Controller {
#Autowired
JdbcTemplate jdbcTemplate;
#GetMapping("/lol")
String lol() {
return "index";
}
}
You annotated your class with #RestController.
What you want is a MVC Controller, so replace it with #Controller.
Here is an example of the documentation :
#Controller
public class HelloController {
#GetMapping("/hello")
public String handle(Model model) {
model.addAttribute("message", "Hello World!");
return "index";
}
}
Put your index.html in src/main/resources/static
and then in your controller
#RequestMapping("/api")
#RestController
public class Controller {
#Autowired
JdbcTemplate jdbcTemplate;
#GetMapping("/lol")
String lol() {
return "index.html";
}
}
Related
I want to simply map my home page with a Spring Controller like this :
package com.douineau.testspringboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/")
public class HomeController {
#GetMapping
// #ResponseBody
public String home() {
return "index";
}
}
I also have index.html in src/main/webapp folder.
But the application does not recognize the mapping, whereas if comment this all, the app recognizes that it is my home page.
What am I missing?
You mention you placed the index.html in your src/main/webapp but as I remember spring boot default configuration, it should be under src/main/resources/templates if it should be handled through your #Controller.
Everything in webapp is exposed "as-is" for eg. assets
You can change #Controller to #RestController.
Your code should be like this.
#RestController
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home() {
return "index";
}
}
or
#RestController
#RequestMapping(value = "/")
public class HomeController {
#GetMapping("")
public String home() {
return "index";
}
}
I try to test my spring app but encounter following problem:
In "normal mode"(mvn spring-boot:run) the app starts as expected and adapterConfig gets set and is NOT NULL. When I start my testclass to test the MVC, adapterConfig does not get set. Spring ignores the whole config class.
test:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = StudentController.class)
public class StudentControllerTests {
#Autowired
private MockMvc mockMvc;
#MockBean
private StudentService service;
#MockBean
private StudentRepository repository;
#Test
public void shouldReturnABC() throws Exception{
MvcResult result = this.mockMvc.perform(get("/students/abc")).andReturn();
}
}
controller:
#RestController
#RequestMapping("/students")
#PermitAll
public class StudentController {
#Autowired
StudentService studentService;
//get
#GetMapping("/abc")
public String abc (){
return "abc";
}
config:
#Configuration
public class SpringBootKeycloakConfigResolver implements KeycloakConfigResolver {
private KeycloakDeployment keycloakDeployment;
private AdapterConfig adapterConfig;
#Autowired
public SpringBootKeycloakConfigResolver(AdapterConfig adapterConfig) {
this.adapterConfig = adapterConfig;
}
#Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
if (keycloakDeployment != null) {
return keycloakDeployment;
}
keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfig);
return keycloakDeployment;
}
}
adapterConfig is null when hitting the test but gets set & created when hitting it the normal way, any idea?
Using #WebMvcTest, the container will inject only components related to Spring MVC (#Controller, #ControllerAdvice, etc.) not the full configuration use #SpringBootTest with #AutoConfigureMockMvc instead.
Spring Boot Javadoc
Keycloak's AutoConfiguration is not included by #WebMvcTest.
You could
Include it manually via #Import(org.keycloak.adapters.springboot.KeycloakSpringBootConfiguration.class)
Or use #SpringBootTest
with spring boot 2.5 i had I had to import KeycloakAutoConfiguration into my test.
#WebMvcTest(value = ApplicationController.class, properties = "spring.profiles.active:test")
#Import(KeycloakAutoConfiguration.class)
public class WebLayerTest {
// ... test code ....
}
I am new to MongoDB and I am trying to use it with my SpringBoot application. I have followed my tutorials online and have downloaded their code and got it execute.
However for whatever reason my project fails to be able to print out
RequestMappingHandlerMapping : Mapped “{[/findAllBooks/{id}],methods=[GET]}”
I was wondering if anyone would be able to advise me if it is due to the nature of my project structure .
I wasn’t sure if my SpringBootMain could see my Controller class.
My project structure is best viewed here
https://github.com/emuldrew855/backend/tree/A/B-Testing/src/main/java/com/ebay/queens/demo
My Controller class
package com.ebay.queens.demo.resource;
#RestController
#RequestMapping("/v2")
public class UserController {
#Autowired
private UserRepository userRepository;
#PostMapping("/AddUser")
public String saveUser(#RequestBody User user) {
userRepository.save(user);
return "Added user with id: " + user.getId();
}
#GetMapping("/all")
public List<User> getAll(){
List<User> users = this.userRepository.findAll();
return users;
}
}
My main class
package com.ebay.queens.demo;
#SpringBootConfiguration
#SpringBootApplication
public class SpringBootMain implements CommandLineRunner {
#Autowired
private TokenUtilityClass tokenUtilityClass;
#Bean ResourceConfig resourceConfig() {
return new ResourceConfig().registerClasses(Version1Api.class, Login.class, SignUp.class, Paypal.class); }
#Override
public void run(String... args) throws Exception {
// test.authenticationToken();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class, args);
}
}
I've figured out why is not working... You are using 2 different WebService API which are incompatible...
Spring-Boot has native API to work with API Rest with #RestController annotation. You don't need to use Glassfish server.
Solution #1
From SpringBootMain remove #Bean ResourceConfig resourceConfig() {...}. Now, you API /v2 will work as expected.
Your API /v1 won't work because it uses other library. You need to change #Path to #GetMapping or #PostMapping and add #RestController into your Version1Api class.
Solution #2
You ignore Spring-Boot native Rest API and implement Glassfish Server.
Add UserController.class reference
#Bean ResourceConfig resourceConfig() {
return new ResourceConfig().registerClasses(Version1Api.class, Login.class, SignUp.class, Paypal.class, UserController.class); }
For UserController change #RestController to #Path("/v2")
#Path("/v2")
public class UserController {
#Autowired
private UserRepository userRepository;
#POST
#Path("/AddUser")
#Produces(MediaType.TEXT_PLAIN)
public String saveUser(#RequestBody User user) {
userRepository.save(user);
return "Added user with id: " + user.getId();
}
#GET
#Path("/all")
#Produces(MediaType.APPLICATION_JSON)
public List<User> getAll(){
List<User> users = this.userRepository.findAll();
return users;
}
}
Now both API will work as expected
I have a #Controller:
#Controller("/")
public class GreetingController {
#GetMapping("/greeting")
public String get() {
return "greeting";
}
}
Also a #RestController:
#RestController("/test")
public class TestRest {
#RequestMapping()
public List<TestDTO> get() {
List<TestDTO> dtos = new ArrayList<>();
dtos.add(new TestDTO("value1","value2"));
dtos.add(new TestDTO("value1","value2"));
return dtos;
}
}
The #Controller works correctly, and serves a static HTML page at src/main/resources/templates/greeting.html
But the #RestController does not work, all I get are 404s.
If I move the method from the #RestController into the #Controller and add a #ResponseBody annotation, it then starts working.
How can I have the controllers as different classes?
#RestController and #Controller do not take the path to the resource as a parameter. Perhaps try something along the lines of...
#RestController
#RequestMapping("/test")
public class TestRest {
#RequestMapping(method = RequestMethod.GET)
public List<TestDTO> get() {
List<TestDTO> dtos = new ArrayList<>();
dtos.add(new TestDTO("value1","value2"));
dtos.add(new TestDTO("value1","value2"));
return dtos;
}
}
You question itself has the answers, for the RESTController to work, you would need to have a #ResponseBody because, for all REST calls, there needs to be response body to return the data.
I hope adding #ResponseBody alone will solve the problem.
I am writing my own app using spring mvc (restful webservice) and hibernate.
The problem is, that I have my method in controller that is mapped to url: PUT /report/
and now, in the request body I send the JSON representation of Report entity. When I run the server, add some entities and then try to edit one, the first attempt succeed but the second and every next fails and returns http 400 code.
So it acts like it could be edited just once? strange
Here is my code:
REPOSITORY:
#Repository
public class ReportHibernateRepository implements ReportRepository {
#PersistenceContext
private EntityManager entityManager;
//.......other methods............
#Override
public Report update(Report report) {
Report report1 = entityManager.find(Report.class, report.getId());
report1.setDate(report.getDate());
report1.setReporter(report.getReporter());
report1.setReportText(report.getReportText());
report1.setTitle(report.getTitle());
return report1;
}
}
SERVICE:
#Service
#Transactional
public class ReportService {
#Autowired
private ReportRepository reportRepository;
//..........other methods...........
public Report update(Report report){
return reportRepository.update(report);
}
}
CONTROLLER:
#Controller
#RequestMapping(value = "/report")
public class ReportController {
#Autowired
private ReportService reportService;
//.........other methods...........
#RequestMapping(value = "/", method = RequestMethod.PUT)
#ResponseBody
#ResponseStatus(HttpStatus.NO_CONTENT)
public void update(#RequestBody Report report){
reportService.update(report);
}
}
Does anybody know what's the problem?