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
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.You can not add constructor parameters without @Autowired or @Inject annotation
Will be like that view reference link
Or