skip to Main Content

I have an application with a spring-boot backend api and Angular10 frontend. When running these locally I have no problems and everything runs fine. I have deployed my application on a Debian VPS with the Angular build running on apache2. But when trying to send requests there I get a 402 not found tot the requested URL.

In Apache I have configured a reverse proxy to acces spring boot:

<VirtualHost *:80>
  DocumentRoot /var/www/html
  ProxyPass /api/ http://localhost:8080/
  ProxyPassReverse /api/ http://37.128.150.186/api/
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

And in my environment.ts file in Angular I specified the base of the url like "/api/" so every request will go to through these URLS with the base port of Apache (:80). But when doing this I get a 404 not found. But when I go to /api/ in the URL I do get shown the "Home controller" of Spring Boot.

Request in browser when trying to send post to spring-boot controller:

Request URL: http://37.128.150.186/api/users
Request Method: POST
Status Code: 404 
Remote Address: 37.128.150.186:80
Referrer Policy: strict-origin-when-cross-origin

Error response:

"timestamp": "2021-05-02T21:15:46.970+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "//users"

The controller I’m trying to send the request to in this example:

@RestController
@RequestMapping(value = "/api/users", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {

    private final UserService userService;
    private final PasswordEncoder encoder;

    public UserController(final UserService userService, final PasswordEncoder encoder) {
        this.userService = userService;
        this.encoder = encoder;
    }

    @GetMapping
    public ResponseEntity<List<UserDTO>> getAllUsers() {
        return ResponseEntity.ok(userService.findAll());
    }

    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable final Long id) {
        return ResponseEntity.ok(userService.get(id));
    }

    /**
     *
     * @param userDTO user type to create new user
     * @return user written to the database
     */
    @PostMapping
    public ResponseEntity<Long> createUser(@RequestBody @Valid final UserDTO userDTO) {
        // create new user
        UserDTO newUser = new UserDTO();
        // set email
        newUser.setEmail(userDTO.getEmail());
        // set firstname
        newUser.setFirstName(userDTO.getFirstName());
        // set lastname
        newUser.setLastName(userDTO.getLastName());
        // set hashed password
        newUser.setPassword(encoder.encode(userDTO.getPassword()));
        // return new user with hashed password
        return new ResponseEntity<>(userService.create(newUser), HttpStatus.CREATED);
    }

    @PutMapping("/{id}")
    public ResponseEntity<Void> updateUser(@PathVariable final Long id,
            @RequestBody @Valid final UserDTO userDTO) {
        userService.update(id, userDTO);
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable final Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }

}

Again when I run the app on my local computer everything works fine. Did I forget something to configure?

2

Answers


  1. The error comes from spring itself.
    I believe that the error lays in that you have configured a context path in one profile but not in the other. (If you hit http://37.128.150.186/api/api/users you get a response).

    What also could be an issue is
    ProxyPassReverse /api/ http://37.128.150.186/api/ I’m unsure if the /api/ needs to be appended to the IP.

    Login or Signup to reply.
  2. You can not add constructor parameters without @Autowired or @Inject annotation
    Will be like that view reference link

    @Autowired
    public UserController(@Qualifier("questionService") UserService userService, @Qualifier("encoder") PasswordEncoder encoder) {
         this.userService = userService;
         this.encoder = encoder;
    }
    

    Or

    @Inject
    public UserController(@Named("questionService") UserService userService, @Named("encoder") PasswordEncoder encoder) {
         this.userService = userService;
         this.encoder = encoder;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search