I am trying to call spring-boot rest controller but it throws o.s.web.servlet.pagenotfound spring boot, I have seen too many answers here but none of these helped me.
controller class is as below
#RestController
#RequestMapping("/users")
public class UsersController {
#Autowired
private UsersRepository usersRepository;
#GetMapping("/users")
public List<Users> getAllUsers() {
return usersRepository.findAll();
}
}
And application.yml is as below
spring.datasource.url = jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=mine
spring.datasource.password=mine
kindly let me know if any further information required
I had the same problem, there should be a problem with your URL. You must be hitting the wrong URL.
I'm assuming you are using Postman for testing the GET Request.
Check if you are hitting through GET Request, and the format is JSON.
And try the below:
#RestController
#RequestMapping(value = "/")
public class UsersController {
#Autowired
private UsersRepository usersRepository;
#GetMapping("/users")
public List<Users> getAllUsers() {
return usersRepository.findAll();
}
}
Related
I'm having some issues with #ConditionaOnProperty and #Configuration behavior not being updated based on the changes in the application properties (config file).
Here's what I have
Configuration
#Configuration
public class RandomRestConfig {
#Value("${external.message.root.uri}")
private String rootUri;
#Bean
#RefreshScope
public RestTemplate randomRestTemplate() {
return new RestTemplateBuilder()
.rootUri(rootUri)
.build();
}
}
Conditional service
#Service
#RefreshScope
#ConditionalOnProperty(value = "external.message.enabled", havingValue = "true")
public class RandomRestService {
#Autowired
#Qualifier("randomRestTemplate")
private RestTemplate restTemplate;
public String getMessageFromService() {
final var response = restTemplate.getForEntity("/trips/trip-text", String.class);
return response.getBody();
}
}
Usage via controller
#RefreshScope
#RestController
public class MessageRestController {
#Value("${message: No message found}")
private String message;
private RandomRestService randomRestService;
public MessageRestController(Optional<RandomRestService> optionalRestService) {
optionalRestService.ifPresent(service -> this.randomRestService = service);
}
#GetMapping("/external-message")
String getExternalMessage() {
if (randomRestService == null) {
throw new RuntimeException("Invalid request - rest is disabled");
}
return randomRestService.getMessageFromService();
}
}
Now, what I'm trying to achieve are
Change the value of the rootUri. I changed it in the config file but it didn't take effect, the old URI is still in effect.
Change the value of external.message.enabled from false to true, but the service is still null in MessageRestController. I was expecting that the bean will be updated.
Now, with both scenarios, I manually triggered the actuator /refresh endpoint and both properties were visible in the response.
[
"config.client.version",
"external.message.root.uri",
"external.message.enabled"
]
Am I missing something? Or is it possible at all?
Thank you!
The application is based on the following stack:
Quarkus 1.5.0
Extensions: vertx-web, reactive-pgclient
The complete codes is here.
I created a Router by #Observes Router.
#ApplicationScoped
public class RoutesObserver {
#Inject PostsHandlers handlers;
public void route(#Observes Router router) {
router.get("/posts").produces("application/json").handler(handlers::getAll);
router.post("/posts").consumes("application/json").handler(handlers::save);
router.get("/posts/:id").produces("application/json").handler(handlers::get);
router.put("/posts/:id").consumes("application/json").handler(handlers::update);
router.delete("/posts/:id").handler(handlers::delete);
router.get("/hello").handler(rc -> rc.response().end("Hello from my route"));
}
}
And extracted the handlers into a standalone bean.
#ApplicationScoped
class PostsHandlers {
private static final Logger LOGGER = Logger.getLogger(PostsHandlers.class.getSimpleName());
PostRepository posts;
ObjectMapper objectMapper;
#Inject
public PostsHandlers(PostRepository posts, ObjectMapper objectMapper) {
this.posts = posts;
this.objectMapper = objectMapper;
}
public void getAll(RoutingContext rc) {
this.posts.findAll().thenAccept(
data -> rc.response()
.write(toJson(data))
.end()
);
}
//... other methods.
}
And the PostRepository used the Java 8 CompletionStage API.
#ApplicationScoped
public class PostRepository {
private static final Logger LOGGER = LoggerFactory.getLogger(PostRepository.class);
private final PgPool client;
#Inject
public PostRepository(PgPool _client) {
this.client = _client;
}
public CompletionStage<List<Post>> findAll() {
return client.query("SELECT * FROM posts ORDER BY id ASC")
.execute()
.thenApply(rs -> StreamSupport.stream(rs.spliterator(), false)
.map(this::from)
.collect(Collectors.toList())
);
}
And when I ran this application and tried to access the /posts. It is frozen and no response printed.
When using the write method, you need to set (beforehand) the content-length header.
There are a several approaches to handle this:
You can use .end(toJson(data)) instead of write(...).end() - it will computed the length automatically
You can use .putHeader("transfer-encoding", "chunked") and you write(...).end() - if you plan to retrieve multiple results, it's interesting as it writes each chunk to the client one by one, avoiding sending a large payload in one go
you can set the content-length as in:
String result = toJson(data);
rc.response()
.putHeader("content-length", Long.toString(result.length()))
.write(result)
.end();
currently I am working on Springboot security, its quite new for me. I followed youtube video tutorial Video
I am getting oauth2 access_token successfully when I use bellow code snippet:-
#SpringBootApplication
public class MathifyApplication {
#Autowired
private PasswordEncoder passwordEncoder;
public static void main(String[] args) {
SpringApplication.run(MathifyApplication.class, args);
}
#Autowired
public void authenticationManager(AuthenticationManagerBuilder builder, UserRepository repository, UserService service) throws Exception {
//Setup a default user if db is empty
User students = new User("stu1", "user", "user", "abc#gmail.com", "1234567890", "12th", "dwarka sec-12",
0, 0 , "may/29/2017", "", Arrays.asList(new Role("USER"), new Role("ACTUATOR")));
if (repository.count()==0){
service.save(students);
}
builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder);
}
private UserDetailsService userDetailsService(final UserRepository repository) {
return userName -> new CustomUserDetails(repository.findByUsername(userName));
}
}
And Controller Class is:-
#RestController
public class LoginController {
#Autowired
private UserService userService;
#RequestMapping(value = "/mathify/getuser/{userId}", method = RequestMethod.GET)
public User getUser(#PathVariable String userId){
System.out.println("Userid "+userId);
return userService.getUser(userId);
}
#RequestMapping(method = RequestMethod.POST, value="/mathify/signup")
public User register(#RequestBody User user){
return userService.doSignup(user);
}
#GetMapping(value="/hi")
public String test(){
return "Oh ! I am fine without secuirity";
}
}
With above code snippet I can get access_token(/oauth/token), and I can also call other controller class private APIs without any issue.
but there is a problem with above code. What? In above code snippet User is hard coded, but when I want to get access_token at the time of user signup it's giving an exception.
2017-06-18 11:04:05.689 ERROR 8492 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer#6b66d7ac to already built object] with root cause
java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer#6b66d7ac to already built object
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.add(AbstractConfiguredSecurityBuilder.java:196) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.apply(AbstractConfiguredSecurityBuilder.java:133) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.apply(AuthenticationManagerBuilder.java:290) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.userDetailsService(AuthenticationManagerBuilder.java:187) ~[spring-security-config-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at com.techiesandeep.mathify.controller.LoginController.register(LoginController.java:40) ~[classes/:na]
for achieving above described feature I did some changes in my Application and Controller
Application Class is As:-
#SpringBootApplication
public class MathifyApplication {
#Autowired
private PasswordEncoder passwordEncoder;
public static void main(String[] args) {
SpringApplication.run(MathifyApplication.class, args);
}
}
and Controller class is as:-
#RestController
public class LoginController {
#Autowired
private UserService userService;
#Autowired
AuthenticationManagerBuilder builder;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private UserRepository repository;
#RequestMapping(value = "/mathify/getuser/{userId}", method = RequestMethod.GET)
public User getUser(#PathVariable String userId){
System.out.println("Userid "+userId);
return userService.getUser(userId);
}
#RequestMapping(method = RequestMethod.POST, value="/user/signup")
public User register(#RequestBody User user) throws Exception {
User u = userService.doSignup(user);
builder.userDetailsService(userDetailsService(repository)).passwordEncoder(passwordEncoder);
return u;
}
private UserDetailsService userDetailsService(final UserRepository repository) {
return userName -> new CustomUserDetails(repository.findByUsername(userName));
}
#GetMapping(value="/hi")
public String test(){
return "Oh ! I am fine without secuirity";
}
}
Any help would be appreciable.thanks
You can call another POST request to get access token.
I am not sure it's the best way, but worked fine with me.
Example code snip inside Signup Request mapping:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", auth_header);
/*auth_header should be Autorization header value that captured from signup request, which is generated by Basic Auth with clientID and secret, for example, "Basic bXktdHJ1c3RlZC1jbGllbnQ6c2VjcmV0" */
HttpEntity<String> entity = new HttpEntity<String>("",headers);
String authURL = "http://localhost:8080/oauth/token?grant_type=password&username=yourusername&password=yourpassword";
ResponseEntity<String> response = restTemplate.postForEntity(authURL, entity, String.class);
System.out.println(response.getBody());
Given the following code sample
-- client library code
#FeignClient("string-service")
public interface StringClient {
#RequestMapping(method = RequestMethod.GET, value = "/microservicestring")
public String home();
}
#Service
public class StringHystrixClient {
private final SpringClient springClient;
//....
}
-- service library code
#RestController
public class StringController implements StringClient {
public String home(){
return "World";
}
}
#SpringBootApplication
#EnableHystrix
#EnableEurekaClient
#EnableFeignClients
public class StringApplication { ....}
If the service library references the client library, when the application gets started, through component scanning we will get to a state where in filling the dependencies from StringHystrixClient, the spring container will not know what to do because there are two beans implementing StringClient.
One solution to avoid this would be to not implement the StringClient in the StringController, but the code duplication from the interface and the rest controller would be error prone. Can somebody point out a more elegant solution to this problem?
In my GWTP application I need to Inject HttpServletRequest, HttpSession as instance variable of ActionHandler.
My ActionHandler is initialized through Spring.
I can't get current Request object through Spring as it instantiates just POJO.
I am thinking about mixing GIN and Spring.
Would I be able inject HttpServletRequest using GIN in my ActionHandler which is instantiated through Spring?????
Is it possible to do following way??
#Configuration
#Import(DefaultModule.class)
public class ServerModule extends HandlerModule
{
#Bean
public UserVerficationActionHandler getUserVerificationActionActionHandler()
{
return new UserVerficationActionHandler();
}
}
public class UserVerficationActionHandler implements ActionHandler<UserVerficationAction, UserVerficationActionResult>
{
#Autowired
private UserService userService;
private Provider<HttpServletRequest> requestProvider;
#Inject
public UserVerficationActionHandler()
{
}
public UserVerficationActionResult execute(UserVerficationAction action, ExecutionContext context) throws ActionException
{
....
}
#Inject
public Provider<HttpServletRequest> setRequestProvider()
{
return requestProvider;
}
}
-------ActionHandler Ends--------
Can somebody let me know Is it possible to do SetterInjection this way?
Second thing, if above is possible then will I be getting current request object using this method?
Thanks in advance.
Bhavesh.