Aop is unable to trigger when userData method is called.
#RequestMapping(value = "/service/userDate", method = RequestMethod.POST)
public ResponseEntity<Response> UserApp(#RequestBody UserVO userVO) {
Response res = new Response(HttpStatus.OK.value());
try {
logger.debug("UserController : </ UserApp> ");
res = userService.userApp(userVO);
return new ResponseEntity<>(res, HttpStatus.OK);
} catch (Exception e) {
logger.error("Exception in approveUser" + e.getMessage());
return new ResponseEntity<>(
new Response(ErocErrorConstants.ERROR_STRING, HttpStatus.EXPECTATION_FAILED.value()),
HttpStatus.BAD_REQUEST);
}
}
package com.gf.service
public class UserService {
#Transactional
public Response userData(User userData) {
}
}
#Aspect
public class EmailAopService {
#Pointcut("execution(* com.gf.service.UserService.userData(..)) && args(userData))")
private void selectAll() {}
#Before("selectAll()")
public void logBefore(User userData) {
//
}
}
Related
I'm creating a component class that overrides a reactive method that calls another microservice "uaa" that validates a token, but when I verify that the token is invalid I throw an exception, but that exception does not catch in my exception controller handler
here is my component class
#Slf4j
#Component
#RequiredArgsConstructor
public class AuthFilter implements GlobalFilter {
private final JwtTokenProviderService jwtTokenProviderService;
private final TokenStatusDaoService tokenStatusDaoService;
private final WebClient webClient;
#Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("something in the way");
List<String> headers = exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION);
if(CollectionUtils.isEmpty(headers)) {
log.trace("Request came without token");
return chain.filter(exchange);
} else {
String authToken = headers.get(0);
log.trace("Request holds a token");
log.debug("Check if token has expired ...");
if(jwtTokenProviderService.isTokenExpired(authToken)) {
log.debug("Token has expired will throw an error");
throw new AuthorizationForbiddenException(AuthorizationForbiddenExceptionTitleEnum.TOKEN_HAS_EXPIRED, "Token has expired");
}else {
log.debug("Check if token is valid and already saved");
String userId = jwtTokenProviderService.getClaimsFromToken(authToken).get(SecurityUtils.IDENTIFIER_KEY).toString();
if(!tokenStatusDaoService.exists(TokenStatusSpecification.withToken(authToken).and(TokenStatusSpecification.withUserId(Long.parseLong(userId))))) {
return webClient.get()
.uri("http://uaa", uriBuilder -> uriBuilder
.path("/validate-token")
.queryParam("token", authToken).build()).retrieve()
.bodyToMono(TokenValidationGetResource.class)
.map(tokenValidationGetResource -> {
if (!tokenValidationGetResource.isValid()) {
log.debug("token is not valid");
throw new AuthorizationForbiddenException(AuthorizationForbiddenExceptionTitleEnum.TOKEN_NOT_VALID, "Token is not valid");
} else {
log.debug("token is valid");
TokenStatusEntity tokenStatusEntity;
try {
tokenStatusEntity = tokenStatusDaoService.findOne(TokenStatusSpecification.withUserId(Long.parseLong(userId)));
} catch (Exception e) {
log.debug("No token defined for user: {}. Will save a new one ...", userId);
tokenStatusEntity = new TokenStatusEntity();
}
tokenStatusEntity.setToken(authToken);
tokenStatusEntity.setUserId(Long.parseLong(userId));
tokenStatusEntity.setStatus(TokenStatusEnum.VALID);
tokenStatusDaoService.save(tokenStatusEntity);
log.debug("Token status entity: {}", tokenStatusEntity);
return exchange;
}
}).flatMap(chain::filter);
} else {
log.debug("Token exists in DB");
return chain.filter(exchange);
}
}
}
}
}
and here is my exception controller handler:
#ControllerAdvice
public class ExceptionControllerImpl implements ExceptionController {
#Override
#ExceptionHandler({
AuthorizationForbiddenException.class
})
public ResponseEntity<ErrorDetailResource> handleGenericExceptions(
AbstractBaseException e, HttpServletRequest request) {
ErrorDetailResource errorDetailResource = new ErrorDetailResource();
errorDetailResource.setTimestamp(Instant.now().toEpochMilli());
errorDetailResource.setTitle(e.getTitle().toString());
errorDetailResource.setCode(e.getTitle().getCode());
errorDetailResource.setDeveloperMessage(e.getClass().getName());
errorDetailResource.setStatus(e.getStatus().value());
errorDetailResource.setDetail(e.getMessage());
return new ResponseEntity<>(errorDetailResource, e.getStatus());
}
}
Hello Those exceptions are thrown on a mono method in a reactive manner, so they can not be caught by controller advice, instead of doing that create a class which will extends the abstract class AbstractErrorWebExceptionHandler
#Component
#Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
public GlobalErrorWebExceptionHandler(GlobalErrorAttributes globalErrorAttributes,
ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) {
super(globalErrorAttributes, new WebProperties.Resources(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters());
super.setMessageReaders(serverCodecConfigurer.getReaders());
}
#Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
final Map<String, Object> errorPropertiesMap = getErrorAttributes(request, ErrorAttributeOptions.defaults());
Throwable error = null;
// here is your abstract base exception
AbstractBaseException baseException = null;
try {
baseException = (AbstractBaseException) getError(request);
} catch (Exception e) {
error = getError(request);
}
HttpStatus statusCode = baseException != null ? baseException.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR;
return ServerResponse.status(statusCode)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(errorPropertiesMap));
}
}
And of course do not forget to add DefaultErrorAttributes
#Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {
#Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Throwable error = null;
// here is your abstract base exception
// cast the error to your exception class
AbstractBaseException baseException = null;
try {
baseException = (AbstractBaseException) getError(request);
} catch (Exception e) {
error = getError(request);
}
Map<String, Object> errorResources = new HashMap<>();
// Define the attribute that you want to return in response body
errorResources.put("attribute1", Instant.now().toEpochMilli());
errorResources.put("attribute2", baseException != null ? baseException.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR);
return errorResources;
}
}
I want to return JSON below.
{
"name": "jackie"
}
Postman is giving me error. Stating
Unexpected 'n'
New to Spring Boot here. 1 day old. Is there a proper way to do this?
// POST method here
#RequestMapping(method = RequestMethod.POST , produces = "application/json")
ResponseEntity<?> addTopic(#RequestBody Topic topic) {
if (Util.save(topicRepository, new Topic(topic.getTopicName(), topic.getQuestionCount())) != null) {
return Util.createResponseEntity("Name : jackie", HttpStatus.CREATED);
}
return Util.createResponseEntity("Error creating resource", HttpStatus.BAD_REQUEST);
}
This is what I use:
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, String>> hello() {
try {
Map<String, String> body = new HashMap<>();
body.put("message", "Hello world");
return new ResponseEntity<>(body, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Create model and store value in that model and return model from controller.
Check Below code.
class User{
private String name;
//getter and setter
}
#RequestMapping(method = RequestMethod.POST , produces = "application/json")
ResponseEntity<User> addTopic(#RequestBody Topic topic) {
User user=new User();
user.setName("myname");
HttpHeaders httpHeaders = new HttpHeaders();
return new ResponseEntity<User>(user, httpHeaders, HttpStatus.CREATED);
}
Try wrapping your response in object.
class Response implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And Controller can be like this:
#RequestMapping(method = RequestMethod.POST , produces = "application/json")
ResponseEntity<?> addTopic(#RequestBody Topic topic) {
if (Util.save(topicRepository, new Topic(topic.getTopicName(), topic.getQuestionCount())) != null) {
Response response = new Response();
response.setName("jackie");
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
return Util.createResponseEntity("Error creating resource", HttpStatus.BAD_REQUEST);
}
#PostMapping("/register/service/provider")
public ResponseEntity<?> registerServiceProvider(#RequestBody ServiceProviderRequestPayload providerContext) {
try {
if (providerContext == null)
throw new BadRequestException("the request body can not be null or empty.");
if (!providerContext.isValid())
throw new BadRequestException("The request body doesn't seems to be valid");
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(new ObjectMapper().writeValueAsString(providerContext));
} catch (BadRequestException | IllegalArgumentException e) {
return ResponseEntity.badRequest().header("message", e.getMessage())
.contentType(MediaType.APPLICATION_JSON).build();
} catch (DuplicateKeyException keyException) {
return ResponseEntity.badRequest().header("message", "There seems to be farmer config" + keyException.getCause())
.contentType(MediaType.APPLICATION_JSON).build();
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
Getting following exception while hitting a Rest endpoint. How do I typecast from String to ProtectPanReplyType class?
Error:
Error - Request: http://localhost:9090/hosted-payments-webapp-1.0.0/pan/protect
raised java.lang.ClassCastException: com.gsicommerce.api.checkout.ProtectPanReplyType cannot be cast to java.lang.String
ProtectPanServiceImpl.java
#Service
public class ProtectPanServiceImpl implements ProtectPanService {
#Override
public ResponseEntity<?> sendProtectPanRequest(ProtectPan protectPan) {
String pan = protectPan.getPaymentAccountNumber();
String tenderClass = protectPan.getTenderClass();
String protectPanRequest = XMLHelper.createProtectPanRequest(pan, tenderClass);
System.out.println("protectPanRequest = " + protectPanRequest);
ResponseEntity<String> response = null;
try {
response = ApiClientUtils.callClientByEndpointandMessage(protectPanRequest, DEV_PUBLIC_API_URL,
ProtectPanReplyType.class);
System.out.println("response.getClass() = " + response.getClass());
//DOES NOT WORK
//ProtectPanReplyType protectPanReplyType = (ProtectPanReplyType)response.getBody();
//THROWS ClassCastException HERE
System.out.println(response.getBody());
} catch (JiBXException e) {
e.printStackTrace();
}
return response;
}
}
ApiClientUtils.java
public ResponseEntity<String> callClientByEndpointandMessage(String xmlRequest, String endpoint, Class<?> replyType) throws JiBXException {
HttpEntity<String> request = createRequestForUser("username", "secret",xmlRequest);
ResponseEntity<String> response = restOperations.postForEntity(endpoint, request, String.class);
ResponseEntity formattedResponse = new ResponseEntity(null, HttpStatus.BAD_REQUEST);
try {
Object jibxObject = JibxHelper.unmarshalMessage(response.getBody(), replyType);
formattedResponse = new ResponseEntity(jibxObject, HttpStatus.OK);
} catch (JiBXException e) {
FaultResponseType faultResponse = JibxHelper.unmarshalMessage(response.getBody(), FaultResponseType.class);
formattedResponse = new ResponseEntity(faultResponse, HttpStatus.BAD_REQUEST);
}
return formattedResponse;
}
ProtectPan.java
public class ProtectPan {
#JsonProperty("paymentAccountNumber")
private String paymentAccountNumber;
#JsonProperty("tenderClass")
private String tenderClass;
public String getPaymentAccountNumber() {
return paymentAccountNumber;
}
public String getTenderClass() {
return tenderClass;
}
}
ProtectPanReplyType.java
public class ProtectPanReplyType {
private String token;
private List<Element> anyList = new ArrayList<Element>();
private String sessionId;
//getters and setter removed for brevity
}
Use ResponseEntity<ProtectPanReplyType> instead ResponseEntity<String>
Build and Return ProtectPanReplyType from your restOperations.postForEntity()
Was finally able to get the object after making following changes.
ApiClientUtils.java
public ResponseEntity<?> callClientByEndpointandMessage(String xmlRequest, String endpoint, Class<?> replyType) throws JiBXException {
HttpEntity<String> request = createRequestForUser("payment", "SONitc2m8y", xmlRequest);
ResponseEntity<String> response = restOperations.postForEntity(endpoint, request, String.class);
ResponseEntity<?> formattedResponse = null;
try {
Object jibxObject = JibxHelper.unmarshalMessage(response.getBody(), replyType);
formattedResponse = new ResponseEntity(jibxObject, HttpStatus.OK);
} catch (JiBXException e) {
FaultResponseType faultResponse = JibxHelper.unmarshalMessage(response.getBody(), FaultResponseType.class);
formattedResponse = new ResponseEntity(faultResponse, HttpStatus.BAD_REQUEST);
}
return formattedResponse;
}
ProtectPanServiceImpl.java
#Override
public ResponseEntity<?> sendProtectPanRequest(ProtectPan protectPan) {
String pan = protectPan.getPaymentAccountNumber();
String tenderClass = protectPan.getTenderClass();
String protectPanRequest = XMLHelper.createProtectPanRequest(pan, tenderClass);
ResponseEntity<?> response = null;
try {
response = publicApiClientUtils.callClientByEndpointandMessage(protectPanRequest, DEV_PUBLIC_API_URL, ProtectPanReplyType.class);
ProtectPanReplyType protectPanReplyType = (ProtectPanReplyType) response.getBody();
System.out.println("protectPanReplyType = " + protectPanReplyType);
} catch (JiBXException e) {
e.printStackTrace();
}
return response;
}
I have a below controller
#Controller
public class TestController{
public Future<ArrayList<String>> global_value = null;
#Autowired
private AsyncService asyncService;
#RequestMapping(value = "/asyncCall", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public String getToken(HttpServletRequest request) {
global_value = asyncService.execute();
return "OK";
}
#RequestMapping(value = "/getAsyncData", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ArrayList<String> getData() {
try {
if (global_value != null && global_value.get().size() > 0) {
return global_value.get();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
When I long poll the getAsncData endpoint, how do I maintain the global_value is just for a request. global_value must be unique for the request scope.
How can I achieve this?
I'm creating a restfull webservice for connecting SAP.So,here web service methods all are work correctly but only one method was throws error,below is that method.
#Path("/Run")
public class RunBapi {
#GET
public Response runBapi() {
return Response.status(200).entity("getUser is called").build();
}
#GET
#Path("/query")
public Response getUsers(
#QueryParam("LIFNR") String accountNO,
#QueryParam("BUKRS") String companyCode,
#QueryParam("EKORG") String po,
#QueryParam("CHAR1") String indicator) {
ExecuteBapi bapi = new ExecuteBapi();
bapi.bapi(accountNO,companyCode,po,indicator);
return Response.status(200).entity("accountNO is: "+accountNO).build();
}
}
and my ExecuteBapi class is
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
public class ExecuteBapi {
public JCO.Client mConnection;
public JCO.Repository mRepository;
public JCO.Function function = null;
public void connectDev()
{
System.out.println("in");
try
{
mConnection = connectSAP();
mConnection.connect();
mRepository = new JCO.Repository("clss", mConnection);
System.out.println("sapconnected");
}
catch(Exception e)
{
System.out.println("error=="+e);
}
}
public JCO.Client connectSAP() {
try {
System.out.println("sap");
setmConnection(JCO.createClient("sapclient",
"userName",
"password",
"en",
"hostname",
"00"));
System.out.println("sap connected");
} catch (Exception ex) {
System.out.println("error in conneting=="+ex);
}
return getmConnection();
}
public JCO.Function createFunction(String name) throws Exception {
try {
IFunctionTemplate ft = mRepository.getFunctionTemplate(name.toUpperCase());
if (ft == null) {
return null;
}
return ft.getFunction();
} catch (Exception ex) {
throw new Exception("Problem retrieving JCO.Function object." + ex);
}
}
public void bapi(String accountNO, String companyCode, String po, String indicator){
System.out.println("bapiex");
connectDev();
}
public static void main(String args[]){
ExecuteBapi bapi = new ExecuteBapi();
connectDev();
}
/**
* #return the mConnection
*/
public JCO.Client getmConnection() {
return mConnection;
}
/**
* #param mConnection the mConnection to set
*/
public void setmConnection(JCO.Client mConnection) {
this.mConnection = mConnection;
}
}
so here we running ExcecuteBapi class manualy SAP will connect,but we run this method in webservice it'll throw error like
org.jboss.resteasy.spi.UnhandledException: java.lang.NoClassDefFoundError:com/sap/mw/jco/JCO
Please help me.