Troubleshooting 401 Unauthorized Errors
Troubleshooting 401 Unauthorized Errors
I used User service another project microservice and both microservices are talking via
authentication commons.
In user service I have security file see below non of my api's are working
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link].
OAuth2AuthorizationServerConfiguration;
import
[Link].O
Auth2AuthorizationServerConfigurer;
import
[Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Configuration
@EnableWebSecurity
public class SecurityConfig {
/*
private BCryptPasswordEncoder bCryptPasswordEncoder;
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/110
public SecurityConfig(BCryptPasswordEncoder bCryptPasswordEncoder) {
[Link] = bCryptPasswordEncoder;
}*/
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
[Link]();
http
.securityMatcher([Link]())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc([Link]()) // Enable OpenID Connect 1.0
)
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
);
return [Link]();
}
// @Bean
// @Order(2)
// public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
// throws Exception {
// http
// .authorizeHttpRequests((authorize) -> authorize
// // .requestMatchers("/admin/**").hasRole("ADMIN") // Only accessible to ADMIN
// // .requestMatchers("/user/**").hasRole("USER") // Only accessible to USER
// //.requestMatchers("/users/login/**").permitAll() // Allow all to login
// //.requestMatchers("/oauth2/**").permitAll()
// // .requestMatchers("users/login").authenticated()
// .anyRequest().permitAll() // All other requests need authentication
// )
//
// // Form login handles the redirect to the login page from the
// // authorization server filter chain
// .formLogin([Link]());
//
// return [Link]();
// }
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 2/110
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> {
try {
requests
.anyRequest().permitAll()
// .requestMatchers("/product/id").authenticated() // Require
authentication for this pattern //("/product/*").authenticated()
//.anyRequest().permitAll() // Allow all other requests without
authentication
.and().cors().disable()
.csrf().disable();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
);
return [Link]();
}
// @Bean
// public UserDetailsService userDetailsService() {
// UserDetails userDetails = [Link]()
// .username("user")
// .password([Link]("password"))
// .roles("USER")
// .build();
//
// return new InMemoryUserDetailsManager(userDetails);
// }
/* @Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient oidcClient = [Link]([Link]().toString())
.clientId("oidc-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.redirectUri("[Link]
.postLogoutRedirectUri("[Link]
.scope([Link])
.scope([Link])
.clientSettings([Link]().requireAuthorizationConsent(true).build())
.build();
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 3/110
@Bean
public JWKSource<SecurityContext> jwkSource() {
KeyPair keyPair = generateRsaKey();
RSAPublicKey publicKey = (RSAPublicKey) [Link]();
RSAPrivateKey privateKey = (RSAPrivateKey) [Link]();
RSAKey rsaKey = new [Link](publicKey)
.privateKey(privateKey)
.keyID([Link]().toString())
.build();
JWKSet jwkSet = new JWKSet(rsaKey);
return new ImmutableJWKSet<>(jwkSet);
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return [Link](jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return [Link]().build();
}
The JWT you are sending is not valid (expired, wrong signing key, wrong audience, etc.), or
Your security filter chain is misconfigured (permitting/denying incorrectly).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 4/110
Your User Service is acting as an Authorization Server (issuing tokens).
Your Product Service is a Resource Server (validates tokens before allowing access).
Right now, your SecurityConfig in User Service has:
java
.anyRequest().permitAll()
That means you’re not really protecting endpoints in User Service (anyone can call them).
But your Product Service must still validate a token, which is why Postman calls fail with 401.
Example:
makefile
java
@Configuration
@EnableWebSecurity
public class ProductSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/products/allProducts").authenticated()
.anyRequest().permitAll()
)
.oauth2ResourceServer(oauth2 -> [Link]()); // enable JWT validation
return [Link]();
}
}
yaml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: [Link] # URL of your User Service (auth server)
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/110
Call your login/authorization endpoint in User Service.
Grab the issued access_token.
Use that token in Postman for calling Product Service.
bash
GET [Link]
Authorization: Bearer <token_from_user_service>
And in Product Service, do you already have a SecurityConfig or only the one you pasted from User
Service?
That way I can show you exact configs for both sides.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
import [Link];
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/110
@RestController
@RequestMapping("/products")
public class ProductController {
private final AuthenticationCommons authenticationCommons;
private final ProductService productService;
private final GlobalExceptionHandler globalExceptionHandler;
@Value("${[Link]}")
private String serverPort;
@Qualifier("eurekaRegistration")
private Registration registration;
@Autowired
public ProductController(@Qualifier("fakeStoreProductService1") ProductService
productService,
AuthenticationCommons authenticationCommons,
GlobalExceptionHandler globalExceptionHandler,
@Qualifier("eurekaRegistration") Registration registration) {
[Link] = productService;
[Link] = authenticationCommons;
[Link] = globalExceptionHandler;
[Link] = registration;
}
//[Link]
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
InstanceInfo instanceInfo = [Link]().getInfo();
String instanceId = (instanceInfo != null) ? [Link]() : "Unknown
Instance";
//[Link]
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
String token) throws InvalidTokenException {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/110
Product product = [Link](id);
[Link]("Check do Api requests are load balanced in product service");
return product;
}
//[Link]
@PostMapping("/all")
public Product postAllProducts(@RequestBody CreateProductRequestDto
createProductRequestDto) {
return [Link](
[Link](),
[Link](),
[Link](),
[Link](),
[Link]()
);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody
CreateProductRequestDto createProductRequestDto) {
return [Link](id, createProductRequestDto);
}
/* @GetMapping("/products1")
public List<ProductIdAndTitleProjection> getProductsByCategoryTitle(@RequestParam("title")
String title) {
return [Link](title);
}*/
//[Link]
@GetMapping("/categories/{title}")
public List<ProductIdAndTitleProjection>
getProductTitlesByCategoryTitle(@PathVariable("title") String categoryTitle) {
return [Link](categoryTitle);
}
//[Link]
@GetMapping("/categories/{title}/{id}")
public Product getFindNameOfProductByCategoryTitleAndProdId(@PathVariable("title")
String title, @PathVariable("id") Long id) {
return [Link](title, id);
}
@GetMapping("/allPrice")
public List<ProductPriceProjection> getPriceFromProduct() {
return [Link]();
}
/*
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/110
Product updatedProduct) {
Product updatedProductResult = [Link](id, updatedProduct);
return new ResponseEntity<>(updatedProductResult, [Link]);
}
*/
So:
If you call /products/allProducts, the 401 is not coming from controller (because you don’t check
token there).
It must be coming from Spring Security filter chain in Product Service.
If you call /products/{id}, then the 401 will come from your manual check if token is
missing/invalid.
🚩 Likely problem
Right now, you haven’t shown me the SecurityConfig in Product Service.
If you copied something like from User Service or left defaults, Spring Boot security by default will
secure everything (every endpoint needs authentication). That explains the 401.
✅ Fix
In your Product Service you need a SecurityConfig like this:
java
@Configuration
@EnableWebSecurity
public class ProductSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> [Link]())
.cors(cors -> [Link]())
.authorizeHttpRequests(auth -> auth
// allow public product list
.requestMatchers("/products/allProducts").permitAll()
// secure product by id (must pass Authorization header)
.requestMatchers("/products/**").authenticated()
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 9/110
// anything else -> permit
.anyRequest().permitAll()
)
.oauth2ResourceServer(oauth2 -> [Link]()); // enables JWT validation
return [Link]();
}
}
yaml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: [Link] # URL of your User Service (auth server)
http
GET [Link]
http
GET [Link]
Authorization: Bearer <token_from_user_service>
That will decide whether we configure permitAll() only for /allProducts or lock down everything by
default.
hey wait whatever required thing i will paste from product service wait
Got it 👍 paste me the Product Service SecurityConfig (or any other related config classes/yml) and I’ll
line it up with your ProductController so we can fix the 401 Unauthorized.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 10/110
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Component
public class AuthenticationCommons {
private final RestTemplate restTemplate;
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 11/110
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
[Link]-with-eureka=true
[Link]-registry=true
[Link]=DEBUG
[Link]=DEBUG
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 12/110
[Link](token) → calls User Service at
pgsql
[Link]
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> [Link]())
.cors(cors -> [Link]())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/products/allProducts").permitAll() // public
.requestMatchers("/products/**").permitAll() // let controller handle
token check
.anyRequest().permitAll()
);
return [Link]();
}
}
Instead of calling User Service from Product Service, you can configure Product Service as a resource
server to directly validate JWT.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 13/110
java
@Configuration
@EnableWebSecurity
public class ProductSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> [Link]())
.cors(cors -> [Link]())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/products/allProducts").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> [Link]()); // enable JWT validation
return [Link]();
}
}
And in [Link]:
yaml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: [Link] # User Service Authorization Server
🚩 My suggestion
Since you already built AuthenticationCommons, go with Option 1 first (disable Spring Security’s default
lock and let your controller do validation).
Later, once things are working, migrate to Option 2 to use Spring Security’s resource server (cleaner &
standard).
👉 Do you want me to rewrite your Product Service SecurityConfig right now for Option 1 (manual
validation) so that Postman stops giving 401?
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
String token) throws InvalidTokenException {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 14/110
}
@GetMapping("/{id}")
public Product getProductById(
@PathVariable("id") Long id,
@RequestHeader("Authorization") String token
) throws InvalidTokenException {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
}
🔎 How it works
1. You expect the client (Postman, or another microservice) to call:
bash
GET [Link]
Authorization: Bearer <jwt-token>
pgsql
[Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 15/110
Wrong token header format:
Make sure you send Authorization: Bearer <token> in Postman.
Your code forwards the header as-is to User Service.
If you send only <token> without Bearer, validation will fail.
Spring Security default filter chain in Product Service:
If you didn’t disable it, Spring itself rejects the request with 401 before your controller runs.
(That’s why I suggested adding a SecurityConfig with .permitAll() earlier.)
✅ Debug checklist
1. In Postman, call:
bash
GET [Link]
Authorization: Bearer <your_valid_token>
🔑 Make sure you actually have a valid JWT from User Service.
2. Add a log in [Link]:
java
bash
POST [Link]
Authorization: Bearer <your_valid_token>
→ Does this return a valid UserDto? If yes, Product Service should work.
This decides whether we need to fix Product Service SecurityConfig or the validate endpoint in User
Service.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 16/110
SMcFHLxkkquFm8FVYl4bBy5HSw76eBwLgd7XfYXbT9Z34jcB"
which is saved in db after user signup i generate not jwt token but random token consider i
saved it to db now when i'm login in that time i'm checking if token is present meaning user is
already sign in so below is api of user service on other project i'm having this api if token is
present in db then only product service will can check product number 6.
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
import [Link];
import [Link].*;
import [Link];
import [Link];
import [Link];
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
public UserController(UserService userService) {
[Link] = userService;
}
@PostMapping("/login")
public LoginResponseDto login(@RequestBody LoginRequestDto loginRequestDto) {
Token token = [Link]([Link](),
[Link]());
return responseDto;
}
/* @PostMapping("/signup")
public ResponseEntity<SignUpResponseDto> signUp(@RequestBody SignUpRequestDto
signUpRequestDto) {
User user = [Link]([Link](),
[Link](),
[Link]());
ResponseEntity<SignUpResponseDto> responseEntity =
new ResponseEntity<>(responseDto, [Link](201));
return responseEntity;
}
*/
/* @PostMapping("/logout")
public ResponseEntity<Void> logout(@RequestBody LogoutRequestDto logoutRequestDto) {
[Link]([Link]());
return new ResponseEntity<>([Link]);
}*/
@PostMapping("/validate")
public UserDto validateToken(@RequestHeader("Authorization") String token) {
User user = [Link](token);
return [Link](user);
}
@PostMapping("/logout")
public ResponseEntity<String> logout(@RequestHeader("Authorization") String token) {
// Remove "Bearer" prefix if the token includes it
if ([Link]("Bearer ")) {
token = [Link](7);
}
if (user == null) {
// If the token was not found or already invalid, return 404 Not Found
return new ResponseEntity<>("Token not found or already logged out.",
HttpStatus.NOT_FOUND);
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 18/110
}
and also i wanted to tell you 7171 port is of api gateway and i register all microservices on
service discovery as i can see everything is working best on port [Link]
[Link]=Api-Gateway
[Link]=7171
[Link]-with-eureka=true
[Link]-registry=true
makefile
Authorization:
TPJvVgm7wsjHlGvsoJcaGcScfv1hu7tmIVeCVF3eqHEz50IlDiyxI6MfdTYrPo8RpsY1WDxudzDvVZG1SMcFHLxkkquFm8FV
Yl4bBy5HSw76eBwLgd7XfYXbT9Z34jcB
java
@PostMapping("/validate")
public UserDto validateToken(@RequestHeader("Authorization") String token) {
User user = [Link](token);
return [Link](user);
}
java
if ([Link]("Bearer ")) {
token = [Link](7);
}
That means validateToken should be updated to behave the same, otherwise it’s inconsistent.
java
@PostMapping("/validate")
public UserDto validateToken(@RequestHeader("Authorization") String token) {
// Handle both "Bearer <token>" and "<token>"
if ([Link]("Bearer ")) {
token = [Link](7);
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 20/110
User user = [Link](token);
return [Link](user);
}
makefile
java
And in AuthenticationCommons:
java
[Link]("Authorization", token);
So if Postman sends Bearer <token>, the Product Service will forward exactly that to User Service → and
User Service will handle stripping it.
bash
POST [Link]
bash
POST [Link]
bash
GET [Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 21/110
Authorization: Bearer <token_from_login>
4. User Service /users/validate is called internally by Product Service → if token is valid, returns UserDto.
hey please take a look at service class too. then come to conclusion
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserServiceImpl(UserRepository userRepository,
BCryptPasswordEncoder bCryptPasswordEncoder,
TokenRepository tokenRepository,
GlobalExceptionHandler globalExceptionHandler) {
[Link] = userRepository;
[Link] = bCryptPasswordEncoder;
[Link] = tokenRepository;
[Link] = globalExceptionHandler;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 22/110
@Override
public Token login(String email, String password) {
Optional<User> optionalUser = [Link](email);
if ([Link]()) { //if email is not present, then throw exception
[Link]();
}
User user = [Link](); //if the fronted(input) password and sign-up saved pw not
matching, then throw exception
if ()) {
throw new WrongPasswordException("A user entered the wrong password for the above
email.");
}
//if both email and password are matching then create token for that user and save it to db
Token token = createToken(user);
return [Link](token);
}
/* @Override
public Token login(String email, String password) {
Optional<User> userOptional = [Link](email);
if ([Link]()) {
// throw an exception or redirect user to signup
return null;
}
[Link](date30DaysFromToday);
[Link](false);
return token;
}
@Override
public User signUp(String name, String email, String password) {
// Optional<User> userOptional = [Link](email);
//
// if ([Link]()) {
// // throw new UserAlreadyExistsException("A user with this email already exists.");
// [Link]();
// }
[Link](user);
return user;
}
@Override
public User validateToken(String token) {
[Link]("Checking do Api requests are load balanced in user service from
Product Service OR NOT ");
Optional<Token> tokenOptional = tokenRepository
.findByValueAndDeletedAndExpiryAtGreaterThan(token, false, new Date());
if ([Link]()) {
// Throw the custom exception when the token is empty,
// throw new InvalidTokenException("The provided token is invalid or expired."); //this
won't work properly
throw new InvalidTokenException();
}
// Return the user associated with the token if it is valid
return [Link]().getUser();
// return null;
}
//why we are using optional here. Is it not guarantee that we will get always token from -
>[Link] this line -> No
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 24/110
//before logout check do token existed in db or not, it might be a case token is deleted by
somebody to check this status make deleted as "false"
@Override
public User logOut(String tokenValue) {
// Attempt to find the token in the database
Optional<Token> optionalToken = [Link](tokenValue);
Perfect 👌
thanks for sharing the UserServiceImpl.
Now I see the full flow:
1. Login → you generate a random 128-char token, save it in DB with expiry date.
2. ValidateToken → checks if that token exists in DB (deleted = false and expiry > now).
If yes → returns the User.
If no → throws InvalidTokenException.
3. Logout → sets deleted=true in DB for that token.
java
@GetMapping("/{id}")
public Product getProductById(
@PathVariable("id") Long id,
@RequestHeader("Authorization") String token
) throws InvalidTokenException {
UserDto userDto = [Link](token); // <---
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
}
return [Link](id);
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 25/110
🔎 Possible Problems
1. Header format mismatch
Right now your [Link]() expects the raw token value (the 128-char
string).
But your frontend / Postman might be sending it as:
makefile
In that case, "Bearer " is also included in @RequestHeader("Authorization") String token and
validation fails.
✅ Fix → Strip the prefix:
java
if ([Link]("Bearer ")) {
token = [Link](7);
}
✅ Suggested Fix
Change your controller like this:
java
@GetMapping("/{id}")
public Product getProductById(
@PathVariable("id") Long id,
@RequestHeader("Authorization") String authHeader
) throws InvalidTokenException {
// Strip Bearer prefix if present
String token = [Link]("Bearer ") ? [Link](7) : authHeader;
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 26/110
throw new InvalidTokenException("Invalid token");
}
return [Link](id);
}
or Authorization: <token>
This will tell me whether the issue is with the "Bearer " prefix or not.
hey why are you more taking about the word "Bearer" i think i have implement in logout
functionality now this fun. is nothing to do with validate right.
Good point 👍 let’s separate the concerns so you don’t get confused:
1. Why I keep talking about Bearer
java
@GetMapping("/{id}")
public Product getProductById(
@PathVariable("id") Long id,
@RequestHeader("Authorization") String token) throws InvalidTokenException {
When the frontend or Postman calls this API, normally the HTTP header looks like:
makefile
"Bearer eyJhbGciOiJIUzI1NiIsInR..."
But your [Link](token) expects only the raw token string stored in DB (like
eyJhbGc...), not "Bearer eyJh...".
So if you don’t strip "Bearer " before validating, it won’t find the token in DB → you get
InvalidTokenException.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 27/110
That’s why I emphasized "Bearer".
2. Logout Functionality
Yes ✅
you’re correct — logout() has nothing to do with validation in getProductById.
Logout is only about marking a token as deleted in DB:
java
🔑 Conclusion
Both validateToken() and logOut() work only if they get the raw token (eyJhb...).
But in real API calls, Authorization header includes "Bearer " prefix.
That’s why you need to strip it before calling your service methods.
✅ Fix in controller:
java
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id,
@RequestHeader("Authorization") String token)
throws InvalidTokenException {
// Remove Bearer prefix if present
if ([Link]("Bearer ")) {
token = [Link](7);
}
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
}
return [Link](id);
}
👉 Do you want me to also show how to centralize this stripping logic in a Spring OncePerRequestFilter,
so you don’t have to write substring(7) in every controller?
you are confusing me more. i have a clean and clear code don't focus on bearer
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 28/110
import [Link];
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
public UserController(UserService userService) {
[Link] = userService;
}
@PostMapping("/login")
public LoginResponseDto login(@RequestBody LoginRequestDto loginRequestDto) {
Token token = [Link]([Link](),
[Link]());
return responseDto;
}
/* @PostMapping("/signup")
public ResponseEntity<SignUpResponseDto> signUp(@RequestBody SignUpRequestDto
signUpRequestDto) {
User user = [Link]([Link](),
[Link](),
[Link]());
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 29/110
SignUpResponseDto responseDto = new SignUpResponseDto();
[Link](user);
// [Link]([Link]());
// [Link]([Link]());
[Link]([Link]); //additional Response status
ResponseEntity<SignUpResponseDto> responseEntity =
new ResponseEntity<>(responseDto, [Link](201));
return responseEntity;
}
*/
/* @PostMapping("/logout")
public ResponseEntity<Void> logout(@RequestBody LogoutRequestDto logoutRequestDto) {
[Link]([Link]());
return new ResponseEntity<>([Link]);
}*/
@PostMapping("/validate")
public UserDto validateToken(@RequestHeader("Authorization") String token) {
User user = [Link](token);
return [Link](user);
}
/* @PostMapping("/logout")
public ResponseEntity<String> logout(@RequestHeader("Authorization") String token) {
// Remove "Bearer" prefix if the token includes it
if ([Link]("Bearer ")) {
token = [Link](7);
}
if (user == null) {
// If the token was not found or already invalid, return 404 Not Found
return new ResponseEntity<>("Token not found or already logged out.",
HttpStatus.NOT_FOUND);
}
check from start to end of conversation then speak take time I already provided the valid
sample token which i'm passing via postamn using keyword "Authorization"
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 30/110
Thanks for the detailed dump — super helpful. I read everything end-to-end. You’re not using JWT;
you’re using an opaque random token stored in DB and validating it via /users/validate. That’s fine.
Given your code and the fact you call the Product API through the API Gateway (7171), there are only a
few places a 401 can come from:
3. User Service /users/validate returning 401 (e.g., token not found/expired) → your
[Link](...) will surface that back, often as a 401 or (if uncaught) a 500.
Since you’re passing the raw token in Authorization (no “Bearer ”), let’s leave that exactly as you want
and fix the real blockers.
Add a simple security config so Spring doesn’t block the request before it reaches your controller:
java
// Product Service
@Configuration
@EnableWebSecurity
public class ProductSecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> [Link]())
.cors(cors -> [Link]())
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll() // you do auth manually via AuthenticationCommons
);
return [Link]();
}
}
If you already have Spring Security on the classpath and don’t provide a chain, Spring will 401
everything by default. This change is the #1 fix so your /products/{id} can actually execute
and call the User Service validator.
If your gateway project has Spring Security in dependencies, add a permissive WebFlux security chain:
java
// API Gateway
@EnableWebFluxSecurity
public class GatewaySecurityConfig {
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
return http
.csrf([Link]::disable)
.authorizeExchange(ex -> [Link]().permitAll())
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 31/110
.build();
}
}
If the gateway doesn’t include Spring Security at all, you can skip this.
java
"[Link]
This must exactly match the [Link] of the User Service (Eureka normalizes to
uppercase; that’s fine). In User Service [Link] (or YAML), ensure:
ini
[Link]=USER-SERVICE-TOKEN-AND-JWT
If the name doesn’t match, the @LoadBalanced RestTemplate can’t resolve it (you’ll get 404/Name
resolution errors rather than 401). From your Eureka UI (8761) verify the APP column shows USER-
SERVICE-TOKEN-AND-JWT.
java
@PostMapping("/validate")
public UserDto validateToken(@RequestHeader("Authorization") String token) {
User user = [Link](token); // expects raw token string
return [Link](user);
}
This is fine because you’re sending the raw token in Postman and forwarding the header as-is from
Product Service. No “Bearer” discussion needed.
Just make sure your exception mapping returns 401 when invalid:
java
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 32/110
E) Product Service: make your validator more robust to upstream 401
java
@Component
public class AuthenticationCommons {
private final RestTemplate restTemplate;
try {
ResponseEntity<UserDto> response = [Link](
"[Link]
[Link],
entity,
[Link]
);
return [Link]();
} catch ([Link] e) {
return null; // invalid token -> let controller throw InvalidTokenException
}
}
}
perl
POST [Link]
Body: { "email": "...", "password": "..." }
pgsql
GET [Link]
Header: Authorization:
TPJvVgm7wsjHlGvsoJcaGcScfv1hu7tmIVeCVF3eqHEz50IlDiyxI6MfdTYrPo8RpsY1WDxudzDvVZG1SMcFHLxkkquFm8FV
Yl4bBy5HSw76eBwLgd7XfYXbT9Z34jcB
If the token exists, is not deleted, and not expired, Product Service will return the product. If not, you’ll
get your InvalidTokenException (which you can map to 401).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 33/110
Two small gotchas I noticed (not 401, but worth fixing)
In ProductController#getAllProducts() you call [Link](), but
eurekaClient isn’t injected anywhere — that can cause NPEs. Either autowire it or remove that
block.
Your UserServiceImpl constructor is private. Spring can reflectively use it, but it’s unusual; consider
making it public or package-private to avoid surprises.
Bottom line
Your 401 isn’t about “Bearer” here — it’s almost certainly the default Spring Security filter in
either Product Service or Gateway blocking requests before your controller runs.
Add the permitAll security chain to Product Service (and Gateway if needed).
Do that, and GET /products/6 via 7171 with your raw Authorization header will work as intended.
{
"timestamp": "2025-08-17T[Link].358+00:00",
"path": "/products/6",
"status": 500,
"error": "Internal Server Error",
"requestId": "10c3f87e-71",
"message": "Connection refused: getsockopt: localhost/[Link]:8092",
"trace": "[Link]$AnnotatedConnectException: Connection refused:
getsockopt: localhost/[Link]:8092\r\n\tSuppressed: The stacktrace has been enhanced by
Reactor, refer to additional information below: \r\nError has been observed at the following
site(s):\r\n\t*__checkpoint ⇢
[Link]
[DefaultWebFilterChain]\r\n\t*__checkpoint ⇢ HTTP GET \"/products/6\"
[ExceptionHandlingWebHandler]\r\nOriginal Stack Trace:\r\nCaused by:
[Link]: Connection refused: getsockopt\r\n\tat
[Link]/[Link](Native Method)\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]([Link])\r\n\
tat
[Link]$[Link](AbstractNioChannel.
java:339)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\t
at [Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link])\
r\n\tat [Link]$[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 34/110
[Link]/[Link]([Link])\r\n"
}
nginx
That means your API Gateway (or some client) is trying to forward the request to the Product Service
on port 8092, but nothing is running there.
✅ Steps to fix
1. Check your Product service port
In your [Link] or [Link] of product service:
properties
[Link]=8092
bash
[Link]
If you still get “Connection refused”, the service isn’t even up.
3. Check Gateway route config
In your [Link] (gateway project), there should be a route like:
yaml
spring:
cloud:
gateway:
routes:
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 35/110
- id: product-service
uri: [Link]
predicates:
- Path=/products/**
👉 So your token validation and controller code is fine, the real issue is just that Product Service is
not reachable on 8092.
Would you like me to help you verify whether your product service is running on 8092 or if we need to
update the gateway config?
{
"timestamp": "2025-08-17T[Link].387+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "[Link]: No instances available for [Link]\r\n\tat
[Link](Bl
[Link])\r\n\tat
[Link](LoadBalance
[Link])\r\n\tat
[Link]$InterceptingRequestExecution.
execute([Link])\r\n\tat
[Link](InterceptingCli
[Link])\r\n\tat
[Link](AbstractB
[Link])\r\n\tat
[Link](AbstractClientHttpRequest.j
ava:66)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link](FakeStoreProductS
[Link])\r\n\tat
[Link]([Link])\r\
n\tat [Link]/[Link].invoke0(Native Method)\r\n\tat
[Link]/[Link]([Link]
a:77)\r\n\tat
[Link]/[Link](DelegatingMethodAccesso
[Link])\r\n\tat [Link]/[Link]([Link])\r\n\tat
[Link](InvocableHandl
[Link])\r\n\tat
[Link](Invoca
[Link])\r\n\tat
[Link]
keAndHandle([Link])\r\n\tat
[Link]
okeHandlerMethod([Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 36/110
[Link]
ndleInternal([Link])\r\n\tat
[Link](Abstract
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\n\t
at
[Link]([Link]
14)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
108)\r\n\tat
[Link]$doFilterInternal$3(FilterChainProxy
.java:231)\r\n\tat
[Link]$FilterObservation$SimpleF
[Link]$wrap$1([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$1([Link])\r\n\
tat
[Link]$wrapSecured$0(O
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](AuthorizationFilt
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 37/110
[Link])\r\n\tat
[Link](Anon
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
([Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](RequestCac
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link]:
107)\r\n\tat
[Link]([Link]:
93)\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 38/110
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
FilterInternal([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](DisableEncod
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$0([Link])\r\n\
tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]$createCacheFil
ter$3([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]([Link])\r\n\tat
[Link]
on$[Link]([Link])\r\n\tat
[Link]([Link]
a:352)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link]:
100)\r\n\tat
[Link]([Link])\r\
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 39/110
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](ServerHttpObserva
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](CharacterEncodingFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link])\r\n\
tat
[Link]$[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n",
"message": "No instances available for [Link]",
"path": "/products/6"
}
✅ How to Fix
In your FakeStoreProductService, you probably wrote something like:
java
But because you annotated your RestTemplate bean with @LoadBalanced, Spring thinks [Link] is
a service name to look up in discovery.
🔧 Solution Options
Option 1: Use a non-loadbalanced RestTemplate for external APIs
java
@Configuration
public class AppConfig {
@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate() {
return new RestTemplate(); // for internal microservices via discovery
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(); // plain RestTemplate for external APIs
}
}
java
@Service
public class FakeStoreProductService {
@Autowired
public FakeStoreProductService(RestTemplate restTemplate) {
[Link] = restTemplate; // plain one, no @LoadBalanced
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 41/110
}
}
Do you want me to refactor your FakeStoreProductService code so it cleanly separates internal service
calls (load balanced) vs external APIs (direct HTTP)?
{
"timestamp": "2025-08-17T[Link].484+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "[Link]: I/O error on POST
request for \"[Link] USER-SERVICE-TOKEN-
AND-JWT\r\n\tat
[Link]([Link]
va:915)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link](AuthenticationCommo
[Link])\r\n\tat
[Link]([Link])\r\
n\tat [Link]/[Link].invoke0(Native Method)\r\n\tat
[Link]/[Link]([Link]
a:77)\r\n\tat
[Link]/[Link](DelegatingMethodAccesso
[Link])\r\n\tat [Link]/[Link]([Link])\r\n\tat
[Link](InvocableHandl
[Link])\r\n\tat
[Link](Invoca
[Link])\r\n\tat
[Link]
keAndHandle([Link])\r\n\tat
[Link]
okeHandlerMethod([Link])\r\n\tat
[Link]
ndleInternal([Link])\r\n\tat
[Link](Abstract
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 42/110
[Link]([Link])\r\n\t
at
[Link]([Link]
14)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
108)\r\n\tat
[Link]$doFilterInternal$3(FilterChainProxy
.java:231)\r\n\tat
[Link]$FilterObservation$SimpleF
[Link]$wrap$1([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$1([Link])\r\n\
tat
[Link]$wrapSecured$0(O
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](AuthorizationFilt
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](Anon
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 43/110
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
([Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](RequestCac
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link]:
107)\r\n\tat
[Link]([Link]:
93)\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 44/110
[Link]
FilterInternal([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](DisableEncod
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$0([Link])\r\n\
tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]$createCacheFil
ter$3([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]([Link])\r\n\tat
[Link]
on$[Link]([Link])\r\n\tat
[Link]([Link]
a:352)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link]:
100)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\
n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 45/110
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](ServerHttpObserva
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](CharacterEncodingFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link])\r\n\
tat
[Link]$[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\nCaused by: [Link]:
USER-SERVICE-TOKEN-AND-JWT\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link].<init>([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n\tat
[Link]/[Link](HttpURLConnectio
[Link])\r\n\tat
[Link]/[Link].plainConnect0([Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 46/110
a:1257)\r\n\tat
[Link]/[Link]([Link]
:1143)\r\n\tat
[Link]/[Link]([Link]
2)\r\n\tat
[Link](SimpleClientHttpReq
[Link])\r\n\tat
[Link](AbstractS
[Link])\r\n\tat
[Link](AbstractClientHttpRequest.j
ava:66)\r\n\tat
[Link]([Link])\r\n\t... 123
more\r\n",
"message": "I/O error on POST request for \"[Link]
JWT/users/validate\": USER-SERVICE-TOKEN-AND-JWT",
"path": "/products/6"
}
pgsql
pgsql
[Link]
but Spring (or your JVM) cannot resolve the hostname USER-SERVICE-TOKEN-AND-JWT.
2. If you are not using Eureka, that name (USER-SERVICE-TOKEN-AND-JWT) must be replaced with a real
host:port like:
bash
[Link]
or
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 47/110
bash
[Link]
java
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
java
👉 Question for you: are you running with Eureka/Service Discovery or just hardcoding URLs
(localhost:port)?
That will decide the correct fix.
{
"timestamp": "2025-08-17T[Link].970+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "[Link]: No instances available for [Link]\r\n\tat
[Link](Bl
[Link])\r\n\tat
[Link](LoadBalance
[Link])\r\n\tat
[Link]$InterceptingRequestExecution.
execute([Link])\r\n\tat
[Link](InterceptingCli
[Link])\r\n\tat
[Link](AbstractB
[Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 48/110
[Link](AbstractClientHttpRequest.j
ava:66)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link](FakeStoreProductS
[Link])\r\n\tat
[Link]([Link])\r\
n\tat [Link]/[Link].invoke0(Native Method)\r\n\tat
[Link]/[Link]([Link]
a:77)\r\n\tat
[Link]/[Link](DelegatingMethodAccesso
[Link])\r\n\tat [Link]/[Link]([Link])\r\n\tat
[Link](InvocableHandl
[Link])\r\n\tat
[Link](Invoca
[Link])\r\n\tat
[Link]
keAndHandle([Link])\r\n\tat
[Link]
okeHandlerMethod([Link])\r\n\tat
[Link]
ndleInternal([Link])\r\n\tat
[Link](Abstract
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\n\t
at
[Link]([Link]
14)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
108)\r\n\tat
[Link]$doFilterInternal$3(FilterChainProxy
.java:231)\r\n\tat
[Link]$FilterObservation$SimpleF
[Link]$wrap$1([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$1([Link])\r\n\
tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 49/110
[Link]$wrapSecured$0(O
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](AuthorizationFilt
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](Anon
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
([Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](RequestCac
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link]:
107)\r\n\tat
[Link]([Link]:
93)\r\n\tat
[Link]$[Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 50/110
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
FilterInternal([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](DisableEncod
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$0([Link])\r\n\
tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link])\r
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 51/110
\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]$createCacheFil
ter$3([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]([Link])\r\n\tat
[Link]
on$[Link]([Link])\r\n\tat
[Link]([Link]
a:352)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link]:
100)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](ServerHttpObserva
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](CharacterEncodingFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 52/110
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link])\r\n\
tat
[Link]$[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n",
"message": "No instances available for [Link]",
"path": "/products/7"
}
arduino
tells us that your RestTemplate is trying to do service discovery lookup on [Link] as if it was a
Eureka service name, not a real external domain.
Why?
✅ Fix
For external APIs (like [Link] never use the @LoadBalanced RestTemplate.
You need two beans:
java
@Configuration
public class RestTemplateConfig {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 53/110
// For external APIs (like [Link])
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
java
@Service
public class FakeStoreProductService {
@Autowired
public FakeStoreProductService(@Qualifier("restTemplate") RestTemplate restTemplate) {
[Link] = restTemplate;
}
👉 So quick recap:
Keep @LoadBalanced RestTemplate only for microservice-to-microservice calls (like Product ↔ User
via Eureka).
Use a normal RestTemplate for external APIs ([Link]).
Do you want me to show you how to cleanly wire both into your ProductService so you can use Eureka
for User Service and call FakeStore API without conflict?
{
"timestamp": "2025-08-17T[Link].296+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "[Link]: Cannot invoke
\"[Link]()\" because
\"[Link]\" is null\r\n\tat
[Link]([Link])\r\n
\tat [Link](Unknown Source)\r\n\tat
[Link]/[Link](DelegatingMethodAccesso
[Link])\r\n\tat [Link]/[Link]([Link])\r\n\tat
[Link](InvocableHandl
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 54/110
[Link])\r\n\tat
[Link](Invoca
[Link])\r\n\tat
[Link]
keAndHandle([Link])\r\n\tat
[Link]
okeHandlerMethod([Link])\r\n\tat
[Link]
ndleInternal([Link])\r\n\tat
[Link](Abstract
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\n\t
at
[Link]([Link]
14)\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
108)\r\n\tat
[Link]$doFilterInternal$3(FilterChainProxy
.java:231)\r\n\tat
[Link]$FilterObservation$SimpleF
[Link]$wrap$1([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$1([Link])\r\n\
tat
[Link]$wrapSecured$0(O
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](AuthorizationFilt
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](ExceptionTranslati
[Link])\r\n\tat
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 55/110
[Link](ExceptionTranslati
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](Anon
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
([Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](RequestCac
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link]:
107)\r\n\tat
[Link]([Link]:
93)\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link](HeaderWriterFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 56/110
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link](SecurityContext
[Link])\r\n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]
FilterInternal([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link](DisableEncod
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]$[Link]
er([Link])\r\n\tat
[Link]$AroundFilterObservation$
[Link]$wrap$0([Link])\r\n\
tat
[Link]$[Link](
[Link])\r\n\tat
[Link]$[Link](
[Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]$createCacheFil
ter$3([Link])\r\n\tat
[Link]$[Link]([Link]:
113)\r\n\tat
[Link]([Link])\r\n\tat
[Link]
on$[Link]([Link])\r\n\tat
[Link]([Link]
a:352)\r\n\tat
[Link]([Link])\r\
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 57/110
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link]:
100)\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](ServerHttpObserva
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link](CharacterEncodingFilte
[Link])\r\n\tat
[Link]([Link])\r\
n\tat
[Link]([Link])
\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]$[Link]([Link])\r\n\
tat
[Link]$[Link]([Link])\r\n\tat
[Link]([Link])\r\n\tat
[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r
\n\tat
[Link]$[Link]([Link])\r\n\tat
[Link]/[Link]([Link])\r\n",
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 58/110
"message": "Cannot invoke
\"[Link]()\" because
\"[Link]\" is null",
"path": "/products/allProducts"
}
csharp
That means in your [Link](), you are directly calling something like:
java
[Link]()...
java
@Autowired
private EurekaClient eurekaClient;
Right now, either you didn’t autowire it or your Spring Boot version doesn’t expose the EurekaClient
bean the same way.
✅ Fix Options
Option 1 (recommended): Don’t use EurekaClient directly
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 59/110
java
[Link]()...
do something like:
java
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
return [Link]();
}
java
@Service
public class ProductService {
@Autowired
@Qualifier("loadBalancedRestTemplate")
private RestTemplate restTemplate;
java
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
public ProductController(EurekaClient eurekaClient) {
[Link] = eurekaClient;
}
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
Application application = [Link]("USER-SERVICE");
InstanceInfo instanceInfo = [Link]().get(0);
String url = "[Link] + [Link]() + ":" + [Link]() +
"/users/products";
return [Link](new RestTemplate().getForObject(url, Product[].class));
}
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 60/110
👉 Question for you:
Do you want me to rewrite your getAllProducts() using RestTemplate (Eureka service-id) or do you
want to stick with the manual EurekaClient way?
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
import [Link];
@RestController
@RequestMapping("/products")
public class ProductController {
private final AuthenticationCommons authenticationCommons;
private final ProductService productService;
private final GlobalExceptionHandler globalExceptionHandler;
@Value("${[Link]}")
private String serverPort;
@Qualifier("eurekaRegistration")
private Registration registration;
@Autowired
public ProductController(@Qualifier("HeyProductService") ProductService productService,
AuthenticationCommons authenticationCommons,
GlobalExceptionHandler globalExceptionHandler,
@Qualifier("eurekaRegistration") Registration registration) {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 61/110
[Link] = productService;
[Link] = authenticationCommons;
[Link] = globalExceptionHandler;
[Link] = registration;
}
//[Link]
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
InstanceInfo instanceInfo = [Link]().getInfo();
String instanceId = (instanceInfo != null) ? [Link]() : "Unknown
Instance";
//[Link]
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
String token) throws InvalidTokenException {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Invalid token");
}
//[Link]
@PostMapping("/all")
public Product postAllProducts(@RequestBody CreateProductRequestDto
createProductRequestDto) {
return [Link](
[Link](),
[Link](),
[Link](),
[Link](),
[Link]()
);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody
CreateProductRequestDto createProductRequestDto) {
return [Link](id, createProductRequestDto);
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 62/110
}
/* @GetMapping("/products1")
public List<ProductIdAndTitleProjection> getProductsByCategoryTitle(@RequestParam("title")
String title) {
return [Link](title);
}*/
//[Link]
@GetMapping("/categories/{title}")
public List<ProductIdAndTitleProjection>
getProductTitlesByCategoryTitle(@PathVariable("title") String categoryTitle) {
return [Link](categoryTitle);
}
//[Link]
@GetMapping("/categories/{title}/{id}")
public Product getFindNameOfProductByCategoryTitleAndProdId(@PathVariable("title")
String title, @PathVariable("id") Long id) {
return [Link](title, id);
}
@GetMapping("/allPrice")
public List<ProductPriceProjection> getPriceFromProduct() {
return [Link]();
}
/*
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody
Product updatedProduct) {
Product updatedProductResult = [Link](id, updatedProduct);
return new ResponseEntity<>(updatedProductResult, [Link]);
}
*/
🔎 The issue
In your controller, you declared:
java
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 63/110
…but you never injected it (@Autowired).
So Spring never sets it → it stays null.
Then, when you call:
java
💥 NullPointerException.
✅ Fix #1 (Inject the EurekaClient properly)
Update your constructor to also inject the EurekaClient:
java
@Autowired
public ProductController(@Qualifier("HeyProductService") ProductService productService,
AuthenticationCommons authenticationCommons,
GlobalExceptionHandler globalExceptionHandler,
@Qualifier("eurekaRegistration") Registration registration,
EurekaClient eurekaClient) { // <--- added here
[Link] = productService;
[Link] = authenticationCommons;
[Link] = globalExceptionHandler;
[Link] = registration;
[Link] = eurekaClient; // <--- assign here
}
If your goal in /allProducts is just to log instance/port info, you don’t need EurekaClient.
You already have it via Spring Cloud’s Registration:
java
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
String instanceId = [Link](); // works with eurekaRegistration
[Link]("Port/Instance registered in Eureka Server: " + instanceId);
[Link]("Request arrived in product service in port no. " + serverPort);
return [Link]();
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 64/110
hey see i fix the error but wanted to know about security spring library.
in product service i have not used spring security library but in user service i used and
connection between both the services are via. authentication commons okay .
But only one api need to be authenticated from user service if token is correct then only we will
get response right. and rest of api's in product controller won't have headers and stuff. unless
and untill i have not used spring "SecurityConfig" that you gave saying i need to permitall
request then only i will be able to get responds right.
My question is i think why i need this config file in product service bcoz i have not used library in
pom file are you getting it. By the if this happens then i think conclusion will be if one
microservice is using spring security and another is just talking via anything to that
microservices whichever is using security library then other who don't use library they must
have "SecurityConfig" bcoz they are anyhow talking to another project which have security
library is this correct.
Great question — and you’re thinking about it in exactly the right way. Here’s the clean truth, no fluff:
What does matter across services is HTTP contract, not Spring Security itself:
If a downstream service (User-Service) requires authentication for the endpoint you call, you
must send whatever credentials that service expects (header, basic auth, OAuth2 client creds,
etc.).
That’s outbound client config, not a server-side SecurityConfig for Product-Service’s own
endpoints.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 65/110
1. Client → API Gateway → Product-Service /products/{id}
2. Product-Service extracts Authorization header
3. Product-Service calls User-Service /users/validate to check the token
4. If valid, return the product
That’s perfectly fine without Spring Security in Product-Service because you’re doing the check in code
(controller/service/interceptor). Only the User-Service needs Spring Security (if you choose), and you
typically permitAll() on /users/validate so other services can call it.
Bottom line: another project using Spring Security does not force you to add Spring Security
in this one.
java
@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
[Link](csrf -> [Link]());
[Link](auth -> auth
.requestMatchers([Link], "/products/{id}").authenticated()
.anyRequest().permitAll()
);
// You can keep your current token validation call inside a filter
// or simply leave it in the controller as you do now.
return [Link]();
}
This way /products/allProducts etc. are open, but /products/{id} requires your custom check.
Gateway validates the token (locally if JWT, or by calling /users/validate), and injects user info to
headers (e.g., X-User-Id) for downstream services.
Product-Service then doesn’t care about Authorization and can stay free of Spring Security.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 66/110
java
@Configuration
public class RestTemplates {
@Bean @LoadBalanced
public RestTemplate internalRestTemplate() { return new RestTemplate(); }
@Bean
public RestTemplate externalRestTemplate() { return new RestTemplate(); }
}
2. “UnknownHostException: USER-SERVICE-TOKEN-AND-JWT”
Happens when:
Checklist
Outbound calls to secured services are handled by HTTP client config (headers/credentials), not by
adding Spring Security to the caller.
Prefer JWT to avoid the network hop for validation (or add caching/circuit breaker if you keep the
DB-backed random token design).
If you keep the current design, consider Resilience4j (timeouts/retries/circuit breaker) around the
/users/validate call.
If you want, I can sketch the two-RestTemplate wiring and small changes in your AuthenticationCommons
and FakeStoreProductService so your errors disappear immediately.
No my current code won't work without SecurityConfig file i have that file
package [Link];
import [Link];
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 67/110
import [Link];
import [Link];
import [Link];
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> {
try {
requests
//.anyRequest().permitAll()
// .requestMatchers("/product/id").authenticated() // Require
authentication for this pattern //("/product/*").authenticated()
.anyRequest().permitAll() // Allow all other requests without
authentication
.and().cors().disable()
.csrf().disable();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
);
return [Link]();
}
}
if i remove this file then i get errors non of api works also u can take a look at pom files too and
let me know
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 69/110
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-security-test</artifactId>
</dependency>-->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
<!-- [Link]
netflix-eureka-client -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>4.1.4</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>[Link]</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>[Link]</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 70/110
</plugin>
</plugins>
</build>
</project>
java
.anyRequest().permitAll()
.and().cors().disable()
.csrf().disable();
Which means → “allow all requests, don’t block APIs, no login page, no CSRF required.”
So even though you’re not directly using Spring Security in Product Service, the dependency you
added (OAuth2 Authorization Server) pulled it in, and that forces you to configure security.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 71/110
In your case:
Product Service only validates tokens by calling User Service (via your authenticationCommons).
That means you don’t need Spring Security at all in Product Service.
The only reason you currently need it is because spring-boot-starter-oauth2-authorization-
server is bringing it in.
If you remove that dependency, your Product Service APIs will work fine without
SecurityConfig.
xml
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
✅ If you plan to run OAuth2 Authorization Server inside Product Service (not recommended
usually):
Then you must keep the dependency, and you’ll also need a SecurityConfig.
hey i'm using global handler let me know is this a correct way to handle exception at method
level code in project
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@ControllerAdvice
public class GlobalExceptionHandler {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 72/110
ErrorHandler errorHandler;
@Autowired
public GlobalExceptionHandler(ErrorHandler errorHandler) {
[Link] = errorHandler;
}
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handlerInvalidTokenException() {
[Link]("Token is null or Invalid");
[Link]("InvalidTokenException");
[Link]([Link](401).value());
return new ResponseEntity<>(errorHandler, [Link](500));
}
}
package [Link];
public InvalidTokenException() {
super();
}
}
if (userDto == null) {
throw new InvalidTokenException();
}
Good that you’re thinking about exception handling at method level 👍 Let’s go through your setup in
depth and refine it.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 73/110
java
@ControllerAdvice
public class GlobalExceptionHandler {
ErrorHandler errorHandler;
@Autowired
public GlobalExceptionHandler(ErrorHandler errorHandler) {
[Link] = errorHandler;
}
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handlerInvalidTokenException() {
[Link]("Token is null or Invalid");
[Link]("InvalidTokenException");
[Link]([Link](401).value());
return new ResponseEntity<>(errorHandler, [Link](500));
}
}
✅ What’s good
You’re using @ControllerAdvice + @ExceptionHandler, which is the right approach for centralized
exception handling in Spring.
Catching your custom InvalidTokenException specifically.
⚠️ Issues
1. Reusing a single ErrorHandler bean –
You’re injecting ErrorHandler as a Spring bean and reusing it across requests. That’s not thread-safe
(imagine two requests failing at the same time → data can mix up).
👉Instead, you should create a new instance inside the handler method.
2. Wrong status code returned –
You set errorCode = 401 but return ResponseEntity(..., 500). That’s contradictory.
👉You should return [Link] (401).
2. InvalidTokenException
java
✅ Looks fine, but usually custom exceptions extend RuntimeException (unchecked) in Spring because
checked exceptions (like Exception) force you to throws everywhere.
3. Controller Method
java
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 74/110
String token) throws InvalidTokenException {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException();
}
✅ Logic is good:
Extract token
Validate
⚠️ Small improvements:
Instead of directly throwing a blank exception, pass a message → throw new
InvalidTokenException("Invalid token")
✅ Improved Version
ErrorHandler class (assuming it’s a DTO)
java
GlobalExceptionHandler
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handlerInvalidTokenException(InvalidTokenException ex) {
ErrorHandler errorHandler = new ErrorHandler();
[Link]([Link]() != null ? [Link]() : "Token is null or
Invalid");
[Link]("InvalidTokenException");
[Link]([Link]());
InvalidTokenException
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 75/110
java
Controller
java
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id,
@RequestHeader("Authorization") String token) {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Invalid or missing token");
}
return [Link](id);
}
🔑 Final Notes
No shared state: Always create fresh ErrorHandler objects.
Correct status codes: Match your error object’s errorCode with ResponseEntity status.
RuntimeException over checked: Keeps controller signatures cleaner.
Scalable: You can add more @ExceptionHandlers for other exceptions (e.g., EntityNotFoundException,
IllegalArgumentException).
👉 Do you want me to also show how you can return a consistent error JSON response for all
exceptions (not just InvalidTokenException) so your API has one standard error format?
you mean
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
String token) throws InvalidTokenException => i'm throwing exception at method level in
Signature right which is called uncheck exception
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 76/110
Example: IOException, SQLException.
Unchecked Exception → extends RuntimeException
You don’t need to declare throws in method signature.
Compiler doesn’t force handling.
Example: NullPointerException, IllegalArgumentException.
java
3. If You Change It
java
java
👉 Notice: No more throws InvalidTokenException in the signature, because now it’s unchecked.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 77/110
Cleaner controller signatures
Spring’s @ExceptionHandler and @ControllerAdvice can still catch them
You don’t clutter code with throws everywhere
✅ So to your question:
throws InvalidTokenException in signature → means it’s a checked exception (currently in
your code).
If you want it to be unchecked, extend RuntimeException instead, and you can drop it from the
method signature.
Do you want me to compare when you should actually use checked vs unchecked exceptions in a
Spring Boot project?
Perfect 👌 let’s walk through it step by step with unchecked exceptions + @ControllerAdvice in Spring
Boot.
java
package [Link];
java
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id,
@RequestHeader("Authorization") String token) {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Token is null or invalid");
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 78/110
return [Link](id);
}
java
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleInvalidTokenException(InvalidTokenException ex) {
ErrorHandler error = new ErrorHandler();
[Link]([Link]());
[Link]("InvalidTokenException");
[Link]([Link]());
👉 Key points:
@ExceptionHandler([Link]) catches all thrown InvalidTokenException
anywhere in your controllers.
4. Example Response
json
{
"message": "Token is null or invalid",
"typeOfException": "InvalidTokenException",
"errorCode": 401
}
@Autowired
public GlobalExceptionHandler(ErrorHandler errorHandler) {
[Link] = errorHandler;
}
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handlerInvalidTokenException() {
[Link]("Token is null or Invalid");
[Link]("InvalidTokenException");
[Link]([Link](401).value());
return new ResponseEntity<>(errorHandler, [Link](500));
}
what is the difference between both code I wrote code which is clean and autowired we need
not to create multiple Error Handler objects right which is best practices
Great question 👍 you’ve spotted a subtle difference in object lifecycle and best practices. Let’s compare
your version vs the one I showed:
Your Code
java
@ControllerAdvice
public class GlobalExceptionHandler {
ErrorHandler errorHandler;
@Autowired
public GlobalExceptionHandler(ErrorHandler errorHandler) {
[Link] = errorHandler;
}
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handlerInvalidTokenException() {
[Link]("Token is null or Invalid");
[Link]("InvalidTokenException");
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 80/110
[Link]([Link](401).value());
return new ResponseEntity<>(errorHandler, [Link](500));
}
}
🔎 Key points:
ErrorHandler is injected once (singleton bean).
Every exception request mutates the same errorHandler object.
In concurrent requests (say, 2 users get invalid token at same time), both will overwrite the same
object → thread safety issues, inconsistent responses.
Also you’re returning 500 (Internal Server Error) instead of 401 (Unauthorized).
My Code
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleInvalidTokenException(InvalidTokenException ex) {
ErrorHandler error = new ErrorHandler(); // new object each time
[Link]([Link]());
[Link]("InvalidTokenException");
[Link]([Link]());
🔎 Key points:
Creates new ErrorHandler object for each exception.
No shared mutable state → thread safe.
Cleaner semantics for error responses.
Status code matches the exception (401).
✅ Best Practice
Always create a fresh error object per request inside the handler.
That way:
No race conditions
Responses don’t get mixed between different requests
No accidental leaking of old error data
If you really want to reduce object creation, you could make ErrorHandler immutable (with final fields,
constructor only) and reuse constants, but in REST APIs, object-per-request is normal and negligible
cost compared to network overhead.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 81/110
👉 So: your version is not safe in concurrent environments because of shared state.
Best practice is my version → stateless @ControllerAdvice, new ErrorHandler per exception.
Do you want me to also show you how to write a generic global handler that can handle all exceptions
without repeating code for each?
how to erase bean or controller advices created in spring container bcoz i'm getting still my set
msgs although i used your code in project
Example:
java
If you do want multiple @ControllerAdvice classes but need one to win, use:
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 82/110
java
@ControllerAdvice
@Order(1) // smaller number = higher priority
public class NewGlobalExceptionHandler { ... }
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleInvalidTokenException(InvalidTokenException ex) {
ErrorHandler error = new ErrorHandler(); // plain POJO, no @Component
[Link]([Link]() != null ? [Link]() : "Token is null or
Invalid");
[Link]("InvalidTokenException");
[Link]([Link]());
java
Would you like me to show you how to log all active @ControllerAdvice beans at startup so you can
confirm which one is still in play?
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 83/110
hey i'm saying you still i'm getting my old msg:
, message=500 : "{"message":"Token empty or Invalid or does not
exists.","errorCode":401,"typeOfException":"TokenEmptyException"}", path=/products/7}]
spring is picking the same msg from its old container tell me how i should tell spring this is
updated once
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleInvalidTokenException(InvalidTokenException
ex) {
ErrorHandler error = new ErrorHandler();
[Link]([Link]());
[Link]("InvalidTokenException");
[Link]([Link]());
But maybe you are throwing a different exception (TokenEmptyException in your log).
If you don’t update the @ExceptionHandler annotation to cover that, Spring will keep using the
other handler.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 84/110
👉 In your log:
bash
typeOfException":"TokenEmptyException"
✅ How to fix
Step 1: Search your project for any other @ControllerAdvice.
Delete or comment out the old handler.
Step 2: Unify your exception classes.
If you are throwing TokenEmptyException, update the handler:
java
@ExceptionHandler({[Link], [Link]})
public ResponseEntity<ErrorHandler> handleInvalidTokenException(RuntimeException ex) {
ErrorHandler error = new ErrorHandler();
[Link]([Link]() != null ? [Link]() : "Token is null or
Invalid");
[Link]([Link]().getSimpleName());
[Link]([Link]());
nginx
hey i tried your all approaches but still spring container is using older bean which i created
at
[Link]([Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 85/110
:102)
at
[Link](DefaultResponseErr
[Link])
at
[Link](DefaultResponseErr
[Link])
at
[Link]([Link]
:63)
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at
[Link](AuthenticationCommo
[Link])
at
[Link]([Link])
at [Link]/[Link].invoke0(Native Method)
at
[Link]/[Link]([Link]
a:77)
at
[Link]/[Link](DelegatingMethodAccesso
[Link])
at [Link]/[Link]([Link])
at
[Link](InvocableHandl
[Link])
at
[Link](Invoca
[Link])
at
[Link]
keAndHandle([Link])
at
[Link]
okeHandlerMethod([Link])
at
[Link]
ndleInternal([Link])
at
[Link](Abstract
[Link])
at
[Link]([Link])
at
[Link]([Link])
at
[Link]([Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 86/110
14)
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at [Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link]$[Link]([Link]:
108)
at
[Link]$doFilterInternal$3(FilterChainProxy
.java:231)
at
[Link]$FilterObservation$SimpleF
[Link]$wrap$1([Link])
at
[Link]$AroundFilterObservation$
[Link]$wrap$1([Link])
at
[Link]$wrapSecured$0(O
[Link])
at
[Link]$[Link](
[Link])
at
[Link](AuthorizationFilt
[Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link](ExceptionTranslati
[Link])
at
[Link](ExceptionTranslati
[Link])
at
[Link]$[Link]
er([Link])
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 87/110
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link](Anon
[Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link]
([Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link](RequestCac
[Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link]([Link]:
107)
at
[Link]([Link]:
93)
at
[Link]$[Link]
er([Link])
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 88/110
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link](HeaderWriterFilte
[Link])
at
[Link](HeaderWriterFilte
[Link])
at
[Link]([Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link](SecurityContext
[Link])
at
[Link](SecurityContext
[Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link]
FilterInternal([Link])
at
[Link]([Link])
at
[Link]$[Link]
er([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 89/110
[Link])
at
[Link](DisableEncod
[Link])
at
[Link]([Link])
at
[Link]$[Link]
er([Link])
at
[Link]$AroundFilterObservation$
[Link]$wrap$0([Link])
at
[Link]$[Link](
[Link])
at
[Link]$[Link](
[Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link]$[Link]([Link]:
113)
at
[Link]$createCacheFil
ter$3([Link])
at
[Link]$[Link]([Link]:
113)
at [Link]([Link])
at
[Link]
on$[Link]([Link])
at
[Link]([Link]
a:352)
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link]([Link]:
100)
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 90/110
[Link]([Link])
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link](ServerHttpObserva
[Link])
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at
[Link](CharacterEncodingFilte
[Link])
at
[Link]([Link])
at
[Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at [Link]([Link])
at
[Link]$[Link]([Link])
at [Link]$[Link]([Link])
at [Link]([Link])
at
[Link]([Link])
at
[Link]$[Link]([Link])
at [Link]$[Link]([Link])
at [Link]/[Link]([Link])
, message=500 : "{"message":"Token empty or Invalid or does not
exists.","errorCode":401,"typeOfException":"TokenEmptyException"}", path=/products/7}]
at
[Link]([Link]
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 91/110
)
...
at
[Link]([Link])
That means:
The error response is not coming from your local GlobalExceptionHandler at all.
It’s coming from a remote API that RestTemplate calls inside your
[Link]() method.
json
✅ What to do
You have two choices:
Catch the HttpServerErrorException that RestTemplate throws when the remote service returns 500, then
translate it into your custom error response:
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleHttpServerError(HttpServerErrorException ex) {
ErrorHandler error = new ErrorHandler();
[Link]("Token is invalid (remote service response overridden).");
[Link]("InvalidTokenException");
[Link]([Link]());
This way your client never sees the raw "Token empty or Invalid or does not exists.".
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 92/110
java
👉 To summarize:
The old message isn’t stuck in Spring’s bean container.
It’s coming from the remote service you call with RestTemplate.
To fix it, you need to catch and rewrap that remote error into your own exception or override it in
your @ControllerAdvice.
Do you want me to show you the cleanest setup where all remote service errors (401, 403, 500) from
RestTemplate are mapped into your own custom exceptions, so you never leak their raw JSON to your
clients?
* It’s coming from a **remote API** that `RestTemplate` calls inside your
`[Link]()` method.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
import [Link];
@RestController
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 93/110
@RequestMapping("/products")
public class ProductController {
private final AuthenticationCommons authenticationCommons;
private final ProductService productService;
private final GlobalExceptionHandler globalExceptionHandler;
@Value("${[Link]}")
private String serverPort;
@Qualifier("eurekaRegistration")
private Registration registration;
@Autowired
public ProductController(@Qualifier("HeyProductService") ProductService productService,
AuthenticationCommons authenticationCommons,
GlobalExceptionHandler globalExceptionHandler,
@Qualifier("eurekaRegistration") Registration registration,
EurekaClient eurekaClient) {
[Link] = productService;
[Link] = authenticationCommons;
[Link] = globalExceptionHandler;
[Link] = registration;
[Link] = eurekaClient;
}
//[Link]
@GetMapping("/allProducts")
public List<Product> getAllProducts() {
InstanceInfo instanceInfo = [Link]().getInfo();
String instanceId = (instanceInfo != null) ? [Link]() : "Unknown
Instance";
//[Link]
@GetMapping("/{id}")
public Product getProductById(@PathVariable("id") Long id, @RequestHeader("Authorization")
String token) {
UserDto userDto = [Link](token);
if (userDto == null) {
throw new InvalidTokenException("Token is null or invalid");
}
//[Link]
@PostMapping("/all")
public Product postAllProducts(@RequestBody CreateProductRequestDto
createProductRequestDto) {
return [Link](
[Link](),
[Link](),
[Link](),
[Link](),
[Link]()
);
}
@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody
CreateProductRequestDto createProductRequestDto) {
return [Link](id, createProductRequestDto);
}
/* @GetMapping("/products1")
public List<ProductIdAndTitleProjection> getProductsByCategoryTitle(@RequestParam("title")
String title) {
return [Link](title);
}*/
//[Link]
@GetMapping("/categories/{title}")
public List<ProductIdAndTitleProjection>
getProductTitlesByCategoryTitle(@PathVariable("title") String categoryTitle) {
return [Link](categoryTitle);
}
//[Link]
@GetMapping("/categories/{title}/{id}")
public Product getFindNameOfProductByCategoryTitleAndProdId(@PathVariable("title")
String title, @PathVariable("id") Long id) {
return [Link](title, id);
}
@GetMapping("/allPrice")
public List<ProductPriceProjection> getPriceFromProduct() {
return [Link]();
}
/*
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody
Product updatedProduct) {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 95/110
Product updatedProductResult = [Link](id, updatedProduct);
return new ResponseEntity<>(updatedProductResult, [Link]);
}
*/
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Component
public class AuthenticationCommons {
private final RestTemplate restTemplate;
Got it 👍
I see what’s happening in your code.
The reason you are still seeing the old error message ( "Token empty or Invalid or does not exists." )
even after updating your GlobalExceptionHandler is because:
➡️ That message is not coming from your Product Service’s GlobalExceptionHandler.
It’s actually coming from the User Service you’re calling here:
java
If the users/validate API in the User Service throws InvalidTokenException, then its own
GlobalExceptionHandler there returns the JSON with message "Token empty or Invalid or does not
exists.".
So your Product Service never gets a chance to apply its own GlobalExceptionHandler — instead, it just
receives that JSON from the remote call and passes it along.
Keep User Service responsible for token validation and error messages.
Then in Product Service, don’t throw InvalidTokenException, just propagate whatever User Service
returns.
Catch the exception (or bad response) from RestTemplate and rethrow your own
InvalidTokenException.
Example:
java
try {
HttpHeaders headers = new HttpHeaders();
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 97/110
[Link]("Authorization", token);
return [Link]();
Now your GlobalExceptionHandler in Product Service will kick in and return your new custom message,
not the one from User Service.
Do you want me to show you how to intercept the RestTemplate error (like HttpClientErrorException)
and map it to your own InvalidTokenException, so that you always control the error response in Product
Service?
Hey based upon developer choice or industry expert experiences which is the best way to
handle exception at Runtime Or Exception meaning unchecked exception or checked exception
is best to use think deeper and tell me
Short answer: in modern Spring apps (esp. microservices), prefer unchecked (runtime) exceptions
almost everywhere. Use checked exceptions only at low-level boundaries where the caller can
immediately recover (I/O, parsing, reflection), then convert them to your own unchecked exceptions
before crossing service/module boundaries.
Here’s the deeper “why” and a clean pattern to follow.
Business/HTTP errors: validation failures (400), not found (404), unauthorized/invalid token
(401/403), domain rule violations (409), etc.
Infrastructure/technical faults you won’t handle locally: downstream 5xx, timeouts, DB errors,
circuit breaker open, etc.
Transactional code: Spring rolls back on RuntimeException by default; checked exceptions need
rollbackFor, which is easy to forget.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 98/110
Use checked (extends Exception) only when:
The method’s immediate caller can and should handle/recover (e.g., retry a local file read, select a
different parser, prompt for different path).
You’re writing a public library API (not a Spring service) and want to force handling of a specific,
recoverable condition.
Avoid exceptions for routine control flow. For expected, frequent “misses” (e.g., cache lookup), return
Option/nullable or a Result type—reserve exceptions for exceptional paths.
A practical pattern
1) Exception hierarchy (unchecked):
java
java
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 99/110
return [Link]();
} catch ([Link] e) {
throw new InvalidTokenException("Token is invalid or expired");
} catch (ResourceAccessException | HttpServerErrorException e) {
throw new DownstreamServiceException("User service unavailable", e);
}
}
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleAppException(AppException ex) {
ErrorHandler dto = new ErrorHandler();
[Link]([Link]());
[Link]([Link]().getSimpleName());
[Link]([Link]());
return [Link]([Link]()).body(dto);
}
Bottom line
Default: unchecked exceptions + centralized mapping.
Boundary rule: catch low-level (often checked) exceptions, decide if recoverable; if not, convert to
your unchecked domain/infrastructure exceptions.
HTTP mapping: 4xx for client issues, 5xx for server/infra; don’t leak downstream payloads.
If you want, I can help refactor your project to this pattern end-to-end (exception classes, mappers, and
the RestTemplate/WebClient translation spots).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 100/110
so you mean uncheck exceptions are best to throw error right? now my question is in service
layer of backend code we need to throw exception at method level right
package [Link];
Great question 👍 — let’s slow this down because you’re mixing two things:
Checked exceptions (extends Exception) → must declare with throws in the method signature.
Unchecked exceptions (extends RuntimeException) → no need to declare throws, they can be
thrown anywhere.
and
java
java
try {
[Link](lectures, instructorId, batchId);
} catch (InvalidLectureException | InvalidInstructorException | InvalidBatchException e) {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 101/110
// handle
}
This is useful only if the caller can immediately do something meaningful with the exception (retry,
substitute, prompt user, etc.).
But in a typical Spring backend service layer → controller → REST API flow, the caller (controller) usually
just bubbles up to the global exception handler. That means checked exceptions here only add
boilerplate and noise.
java
java
The exception flows up, your @ControllerAdvice catches it, and you map it to a proper HTTP response
(400/404 etc.).
🔑 Rule of Thumb:
Spring applications (REST, microservices, backend apps):
→ Use unchecked exceptions in your exceptions package (extends RuntimeException).
→ Handle them centrally with @ControllerAdvice.
Libraries, utilities, or API code where caller must handle:
→ Use checked exceptions (extends Exception).
Example: a CSV parsing library throwing InvalidCsvFormatException (caller can switch to another
parser or skip the file).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 102/110
Do you want me to rewrite your scheduleLectures method + exception classes in the clean, Spring-
style unchecked + @ControllerAdvice approach so you have a working template?
* **Checked exceptions** (`extends Exception`) → must declare with `throws` in the method
signature. * **Unchecked exceptions** (`extends RuntimeException`) → no need to declare `throws`,
they can be thrown anywhere.
hey please add points like try catch block. for which exception we must use and so on
Perfect 👍 let’s put everything together in a developer-friendly guide so you’ll know when to use
checked vs unchecked exceptions, and when to wrap code in try–catch.
👉 Example:
java
try {
FileInputStream fis = new FileInputStream("[Link]");
} catch (FileNotFoundException e) {
// Handle: maybe prompt user to select another file
}
👉 Example in Spring:
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 103/110
java
Use try–catch for checked exceptions when you can do something useful right there:
Retry logic
Cleanup resources
Fallback to defaults
Don’t wrap unchecked exceptions in try–catch unless you really have a recovery/fallback plan.
Example: catching NullPointerException is almost always a code smell.
java
try {
[Link]("SOME QUERY");
} catch (SQLException e) {
throw new DatabaseAccessException("DB error occurred", e);
}
3. Global Handling:
Use @ControllerAdvice to centralize the mapping of exceptions → HTTP status codes + JSON
responses.
📝 Rule of Thumb
Checked (Exception): caller must handle → IO, JDBC, external API.
Unchecked (RuntimeException): programmer/business errors → invalid state, bad input, missing
entity.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 104/110
try–catch only where you can recover. Otherwise, let it bubble.
👉 Would you like me to create a ready-made template for your project with:
1 checked exception use case (like file upload)
1 unchecked exception use case (like invalid product ID)
and the global @ControllerAdvice handler for both?
But in a typical Spring backend service layer → controller → REST API flow, the caller (controller)
usually just **bubbles up** to the global exception handler. That means checked exceptions here
only add boilerplate and noise.
so you mean in controller we shouldn't be using try catch block right? which is bad to use
1. Boilerplate & Repetition – every controller method would need the same repetitive error handling
code.
2. Hard to Maintain – if you change error format, you must update all controllers.
3. Breaks Separation of Concerns – controller should just handle input → service → output, not deal
with exception formatting.
✅ Best Practice
Don’t use try–catch in controller for business/domain errors.
Throw unchecked exceptions (RuntimeException) from service layer.
Handle them centrally with @ControllerAdvice (global exception handler).
👉 Example:
Service layer
java
Controller
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 105/110
java
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return [Link](id);
// no try–catch here
}
java
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ErrorHandler> handleProductNotFound(ProductNotFoundException ex) {
ErrorHandler error = new ErrorHandler();
[Link]([Link]());
[Link]("ProductNotFoundException");
[Link](HttpStatus.NOT_FOUND.value());
You need very specific handling for that one endpoint only (rare case).
Example: calling a third-party API where you want to fallback with a default response instead of
failing globally.
👉 Do you want me to show you one real case where a try–catch in controller is acceptable, so you’ll
see the contrast clearly?
unchecked exceptions
meaning at the time of runtime we are throwing exception
Yes ✅ — exactly.
When we say unchecked exceptions (like RuntimeException and its subclasses), it means:
java
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 106/110
// ProductNotFoundException extends RuntimeException (unchecked)
}
java
That “throws” part is only required for checked exceptions (extends Exception).
🔑 Difference
Checked Exception → must declare in method signature (throws ...), compiler forces handling.
Unchecked Exception (Runtime) → no need to declare, thrown freely at runtime, best for
business/domain logic in modern Spring apps.
So yes 👍in controllers/services, we generally throw runtime (unchecked) exceptions → and then
Spring’s @ControllerAdvice catches them at runtime and formats a proper response.
👉 Do you want me to show you a comparison of your InvalidInstructorException in both ways — once
as checked and once as unchecked, with pros/cons?
Do you want me to **rewrite your scheduleLectures method + exception classes** in the clean,
Spring-style unchecked + `@ControllerAdvice` approach so you have a working template? Ask
ChatGPT
please write that will helpful for me
Perfect 👍 let’s take your scheduleLectures example and write it in both ways:
Exception Classes
java
package [Link];
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 107/110
}
}
Service Layer
java
if (instructorId == null) {
throw new InvalidInstructorException("Instructor not valid.");
}
if (batchId == null) {
throw new InvalidBatchException("Batch not valid.");
}
Controller
Exception Classes
java
package [Link];
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 108/110
}
}
Service Layer
java
if (instructorId == null) {
throw new InvalidInstructorException("Instructor not valid.");
}
if (batchId == null) {
throw new InvalidBatchException("Batch not valid.");
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({
[Link],
[Link],
[Link]
})
public ResponseEntity<ErrorHandler> handleCustomExceptions(RuntimeException ex) {
ErrorHandler error = new ErrorHandler();
[Link]([Link]());
[Link]([Link]().getSimpleName());
[Link](HttpStatus.BAD_REQUEST.value());
🔎 Which is better?
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 109/110
Checked Exceptions → Good when you want to force the caller to handle. But in big apps (like
Spring Boot) this creates too much noise.
Unchecked Exceptions → Cleaner, modern best practice in Spring Boot. Let the global exception
handler deal with them, no need to litter code with throws and try/catch.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 110/110