Home > OS >  Springboot Get Api Endpoint returns 404 not found
Springboot Get Api Endpoint returns 404 not found

Time:10-30

I'm trying to create a Springboot Get API endpoint but I get a 404 not found error' here is my code

profile.java

@Getter
@Setter
public class Profile {

    private String slackUsername;
    private Boolean backend;
    private Integer age;
    private  String bio;

ProfileController

@RestController
public class ProfileController {

    @Autowired
    private Profile profile;

    @GetMapping(path = "/profile")
    private ResponseEntity<String> userInfo(){

        profile.setSlackUsername("Ajava");
        profile.setBackend(true);
        profile.setAge(00);
        profile.setBio("My name is Anakhe Ajayi, I'm learning Java everyday and I love Jesus");
        return ResponseEntity.ok(profile.toString());
    }

Main

@SpringBootApplication
@ComponentScan("com/ajavacode/HNGBackendStage1/api.profile")
public class HngBackendStage1Application {

    public static void main(String[] args) {
        SpringApplication.run(HngBackendStage1Application.class, args);
    }

}

Project folder structur

porm.xml enter image description here

CodePudding user response:

Please fix the value in @ComponentScan annotation like this and try again.

@SpringBootApplication
@ComponentScan(basePackages = "com.ajavacode.HNGBackendStage1")
public class HngBackendStage1Application {

    public static void main(String[] args) {
        SpringApplication.run(HngBackendStage1Application.class, args);
    }

}

Also there is an issue in ProfileController class, you are auto wiring Profile class inside it. Profile class is not a bean so this is incorrect and userInfo() method is private, it should be public. Here is the fixed version.

@RestController
public class ProfileController {


    @GetMapping(path = "/profile")
    public ResponseEntity<String> userInfo(){
        Profile profile=new Profile();
        profile.setSlackUsername("Ajava");
        profile.setBackend(true);
        profile.setAge(00);
        profile.setBio("My name is Anakhe Ajayi, I'm learning Java everyday and I love Jesus");
        return ResponseEntity.ok(profile.toString());
    }

CodePudding user response:

You have to check some items in your code;

  1. Make sure the endpoint you are sending request , is correct .
  2. Add @RequestMapping("Profile") to the controller to avoid repeated endpoint and reduce the ambiguity
  3. Make sure your pom is correct

CodePudding user response:

Looking at your code, there are a few things to mention.

First of all, your package structure looks good (besides the fact that I, personally, would keep everything lowercase).

With the package structure that you have in place, you actually don't need any @ComponentScan annotation at all. The annotation @SpringBootApplication at your main class by default scans for components with the package of that class as the base package. So you only need to set something if you want to explicitly scan for components in some other package, e.g., either at a higher level or if you want to skip packages in the hierarchy.

Next thing is the controller. Question here is: What do you actually want to achieve?

I assume that you want to build an application that provides a GET /profile endpoint that returns a response object like the example below:

{

  "slackUsername": "alice",
  "backend": false,
  "age": 42,
  "bio": "I'm just an example"
}

If my understanding is correct, there is at least one thing that is a bit odd: Currently, you defined a controller that would return the String representation of the Profile object. That isn't necessarily something as shown in the example above. If you do not override the toString() method, the result would be something like com.ajavacode.HNGBackendStage1.api.Profile@6d06d69c (see this Baeldung article for instance). And even if you use Lombok's @Data or @ToString annotations, the result will not be a JSON or XML representation but something that is suitable for logging, for instance.

Spring will already take care of the serialization into JSON (or XML) format. In your controller you can just return the Profile object or, alternatively, a ResponseEntity<Profile>:

@GetMapping(path = "/profile")
public Profile userInfo(){
  Profile profile=new Profile();
  profile.setSlackUsername("Ajava");
  profile.setBackend(true);
  profile.setAge(00);
  profile.setBio("My name is Anakhe Ajayi, I'm learning Java everyday and I love Jesus");
  return profile;
}

The above example would create a response with the profile as the response body and HTTP status code 200 OK. In case you use ResponseEntity, you could also adjust the HTTP status code but in your case that probably is not necessary (yet).

Autowiring the Profile class also is not correct, as already mentioned. You only need to autowire classes beans, i.e., classes that are annotated with @Component, @Service, or @Repository. The class you "autowired" is just a POJO class representing some "data object", nothing that provides any kind of business logic.

  • Related