I am learning java and using spring boot to develop web app. I am using #controllerAdvice to catch all the exceptions but none of my exceptions is being intercepted by it. I am using spring boot 2.6.2. git repo https://github.com/jitenderchand1/java-microservices
Controller file
package com.learning.rest.webservices.restfulwebservices.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping("/user-service")
public class UserController {
#Autowired
private UserDaoService service;
#GetMapping(path = "/users")
public List<User> retrieveAllUser() {
return service.getAllUser();
}
#GetMapping(path = "/users/{id}")
public User retrieveOneUser(#PathVariable Integer id) {
User user = service.fineOne(id);
if(user == null){
throw new UserNotFoundException("id -" + id);
//throw new Exception();
}
return user;
}
#PostMapping(path = "/user/save")
public ResponseEntity<User> saveUser(#RequestBody User user) {
User savedUser = service.save(user);
return new ResponseEntity(savedUser, HttpStatus.CREATED);
}
}
custom Exception handler
package com.learning.rest.webservices.restfulwebservices.user;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.util.Date;
#ControllerAdvice
#RestController
public class CustomException extends ResponseEntityExceptionHandler {
#ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), "I messed up", request.getDescription(true));
return new ResponseEntity<>(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
#ExceptionHandler(UserNotFoundException.class)
public final ResponseEntity<Object> handleUserNotFoundException(UserNotFoundException ex, WebRequest request) {
ExceptionResponse exceptionResponse = new ExceptionResponse(new Date(), "You are not from this world",
request.getDescription(false));
return new ResponseEntity(exceptionResponse, HttpStatus.NOT_FOUND);
}
}
Related
I have a problem with my REST app. Here is the git link to ease your burden: https://github.com/TheNiceGuy123/AstonishingBackEnd
Here is the raw code also:
Classes posted in order:
Employee Controller:
package com.example.csmartbackend.controller;
import com.example.csmartbackend.model.Employee;
import com.example.csmartbackend.modeldto.EmployeeDto;
import com.example.csmartbackend.service.EmployeeService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.UUID;
#RestController
#RequestMapping("employee")
#RequiredArgsConstructor
public class EmployeeController
{
private final EmployeeService employeeService;
#GetMapping("find/{Cnp}")
public ResponseEntity<Employee> findByCNP(#PathVariable("Cnp") String Cnp)
{
Employee employee = employeeService.findByCnp(Cnp);
HttpHeaders header = new HttpHeaders();
header.add("Desc","Getting employee by id.");
return ResponseEntity.status(HttpStatus.OK).headers(header).body(employee);
}
}
Employee Service:
package com.example.csmartbackend.service;
import com.example.csmartbackend.mapper.EmployeeMapper;
import com.example.csmartbackend.model.Employee;
import com.example.csmartbackend.modeldto.EmployeeDto;
import com.example.csmartbackend.repository.EmployeeRepository;
import exception.general.TargetNotFoundException;
import exception.requestsexceptions.CNPNotFoundException;
import exception.requestsexceptions.EmployeeNotFoundException;
import exception.requestsexceptions.InvalidIdException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
#Service
#RequiredArgsConstructor
#Transactional
public class EmployeeService implements EmployeeServiceImpl
{
private final EmployeeRepository employeeRepository;
private final ContractService contractService;
private final AdressService adressService;
public Employee findByCnp(String Cnp) throws CNPNotFoundException
{
Optional<Employee> employeeOptional = Optional.ofNullable(employeeRepository.findByCnp(Cnp));
if(employeeOptional.isPresent())
return employeeOptional.get();
else
throw new CNPNotFoundException("No employee found.");
}
}
Global Exception Handler:
package exception.requestsexceptions;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
#ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler
{
#Override
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported
(HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Request method not supported.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#Override
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported
(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Media method not supported.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#Override
protected ResponseEntity<Object> handleMissingPathVariable
(MissingPathVariableException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Path variable is missing.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#Override
protected ResponseEntity<Object> handleMissingServletRequestParameter
(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Request parameter is missing.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#Override
protected ResponseEntity<Object> handleTypeMismatch
(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Mismatch of type.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#Override
protected ResponseEntity<Object> handleHttpMessageNotReadable
(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Request body is not readable.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, status, LocalDateTime.now());
return ResponseEntity.status(status).body(apiErrorModel);
}
#ExceptionHandler(EmployeeNotFoundException.class)
public ResponseEntity<Object> handleEmployeeNotFoundException(EmployeeNotFoundException ex)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Employee not found.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, HttpStatus.BAD_REQUEST, LocalDateTime.now());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(apiErrorModel);
}
#ExceptionHandler(CNPNotFoundException.class)
public ResponseEntity<Object> handleInvalidCNPException(CNPNotFoundException ex)
{
String message = ex.getMessage();
List<String> details = new ArrayList<>();
details.add("Employee with the given CNP not found.");
ApiErrorModel apiErrorModel = new ApiErrorModel(message, details, HttpStatus.NOT_FOUND, LocalDateTime.now());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(apiErrorModel);
}
}
CNPNotFoundException class:
package exception.requestsexceptions;
public class CNPNotFoundException extends RuntimeException
{
public CNPNotFoundException(String message) { super(message); }
}
ApiErrorModel class:
package exception.requestsexceptions;
import lombok.*;
import org.springframework.http.HttpStatus;
import java.time.LocalDateTime;
import java.util.List;
#Setter
#Getter
#NoArgsConstructor
#AllArgsConstructor
#ToString
public class ApiErrorModel
{
String message;
List<String> details;
HttpStatus status;
LocalDateTime timestamp;
}
I want to give some relevant informations to the user like in the second picture but in postman everything remains at the default level to call it like that, like my code from the handler is not even there. Is any logic or annotation that I miss?
This is how it looks on my side
This is how it should look like
Thank you for your time!
Problem is when a class is annotated with the #SpringBootApplication without any attribute SpringBoot only scans the package and its subpackages where the class itself is located.
In your case it means SpringBoot only looking for any Spring components under com.example.csmartbackend package while you put GlobalExceptionHandler class in exception.requestsexceptions package.
To fix it you have two choices:
put the exception package under com.example.csmartbackend, so it would be com.example.csmartbackend.exception.requestsexception.GlobalExceptionHandler
tell spring to scan the exception package as well, either by using scanBasePackageClasses or scanBasePackages attribute, e.g #SpringBootApplication(scanBasePackageClasses = {CSmartBackEndApplication.class, GlobalExceptionHandler.class})
I'm struggling a lot with spring-boot custom exception handling. Customer exception is not getting caught with exception handler. REST API works fine for valid request payload. I'm trying to send error response when there's an error. But error response is always empty with status code 200 instead of 404.
Controller
package com.company.paypage.v2.controller;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.company.paypage.exception.*;
import com.company.paypage.model.ErrorMessageConstants;
import com.company.paypage.v2.model.ConfigPayload;
import com.company.paypage.v2.model.ConfigResponse;
import com.company.paypage.v2.services.FeatureConfigService;
import lombok.extern.slf4j.Slf4j;
#Slf4j
#RestController
#RequestMapping(value = "v2/setup")
public class FeatureConfigController {
#Autowired
private FeatureConfigService featureconfigService;
/*
features config endpoint
*/
#RequestMapping(value = "/config", method = POST, consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ConfigResponse setupConfigRequest(#Valid #RequestBody ConfigPayload payload, HttpServletRequest request, HttpServletResponse servResponse) {
log.info("Processing the feature config request for " + payload.getPage_type());
ConfigResponse response = null;
try {
response = featureconfigService.processConfigRequest(payload);
System.out.println(response);
if(response == null) {
throw new FeatureConfigException(ErrorMessageConstants.NOT_FOUND, "Error while generating feature config response.....");
}
} catch (FeatureConfigException e){
log.error("Exception:", e);
}
return response;
}
}
Exception class
package com.company.paypage.exception;
public class FeatureConfigException extends Exception {
String code;
String message;
public FeatureConfigException(String code, String message) {
super(message);
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Exception handler
package com.company.paypage.exception;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;
import com.company.paypage.model.ApplicationConstants;
import com.company.paypage.model.ErrorCodeConstants;
import com.company.paypage.model.ErrorMessageConstants;
import com.company.paypage.model.GeneralErrorInfo;
import com.company.paypage.model.Payment;
import com.company.paypage.model.SetupResponse;
import com.company.paypage.v2.model.ConfigResponse;
import lombok.extern.slf4j.Slf4j;
#Slf4j
#ControllerAdvice
public class GeneralExceptionHandler{
#ExceptionHandler(FeatureConfigException.class)
protected ResponseEntity<ConfigResponse> handleFeatureConfigException(FeatureConfigException ex, HttpServletRequest request){
GeneralErrorInfo generalErrorInfo = new GeneralErrorInfo().withCode(ex.getCode());
generalErrorInfo.setMessage(ex.getMessage());
String referenceId =(String) request.getAttribute(ApplicationConstants.REFERENCE_ID);
ConfigResponse configResponse = buildConfigResponse(generalErrorInfo, referenceId);
log.error("{} {}-{}"
, ex.getMessage()
, request.getHeader(ApplicationConstants.X_GP_REQUEST_ID)
, referenceId
, ex);
return new ResponseEntity<ConfigResponse>(configResponse, addCustomerHeaders(request), HttpStatus.BAD_REQUEST);
}
#SuppressWarnings("null")
ConfigResponse buildConfigResponse(GeneralErrorInfo generalErrorInfo, String referenceId) {
ConfigResponse configResponse = new ConfigResponse();
configResponse.setError(generalErrorInfo);
configResponse.setAutocomplete((Boolean) null);
configResponse.setRefund((Boolean) null);
configResponse.setSplit_payment((Boolean) null);
configResponse.setTender_type(null);
configResponse.setVoidd((Boolean) null);
return configResponse;
}
}
ConfigResponse model
package com.company.paypage.v2.model;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.company.paypage.model.GeneralErrorInfo;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"tender_type",
"autocomplete",
"split_payment",
"refund",
"void",
"error"
})
public class ConfigResponse implements Serializable {
#JsonProperty("tender_type")
private TenderType tender_type;
#JsonProperty("autocomplete")
private boolean autocomplete;
#JsonProperty("split_payment")
private boolean split_payment;
#JsonProperty("refund")
private boolean refund;
#JsonProperty("void")
private boolean voidd;
#JsonProperty("error")
private GeneralErrorInfo error;
public TenderType getTender_type() {
return tender_type;
}
public void setTender_type(TenderType tender_type) {
this.tender_type = tender_type;
}
public boolean isAutocomplete() {
return autocomplete;
}
public void setAutocomplete(boolean autocomplete) {
this.autocomplete = autocomplete;
}
public boolean isSplit_payment() {
return split_payment;
}
public void setSplit_payment(boolean split_payment) {
this.split_payment = split_payment;
}
public boolean isRefund() {
return refund;
}
public void setRefund(boolean refund) {
this.refund = refund;
}
public boolean isVoidd() {
return voidd;
}
public void setVoidd(boolean voidd) {
this.voidd = voidd;
}
public GeneralErrorInfo getError() {
return error;
}
public void setError(GeneralErrorInfo error) {
this.error = error;
}
public ConfigResponse withError(GeneralErrorInfo error) {
setError(error);
return this;
}
}
What could be the issue here? What am I missing to get proper error in JSON format in response?
You have to define the code of an exception. Here you can find different variants of how to handle exceptions for REST: link
I have code like this below :
MyExceptionHandler {
#ExceptionHandler(Exception.class)
public Object handleMvc(Exception ex, org.springframework.http.server.ServerHttpRequest request) {
return request.getbody;
}
#ExceptionHandler(Exception.class)
public Object handleReactive(Exception ex, org.springframework.http.server.reactive.ServerHttpRequest request) {
return request.getBody();
}
}
The code above produces IllegalStateException: Ambiguous #ExceptionHandler method mapped for Exception error.
Is there a way to handle both MVC and reactive requests in the ControllerAdvice? I'm working on a common project that works across multiple projects using different httprequest type.
**In spring boot using this**
package com.example.demo.exception;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
#ControllerAdvice
public class UserCVExceptionController {
#ExceptionHandler(value = UserCVNotfoundException.class)
public ResponseEntity<Object> exceptionMsg(UserCVNotfoundException exception) {
Map<String, String> headers=new HashMap<String, String>();
headers.put("Status", "404");
headers.put("Message", "User Not found");
headers.put("User", exception.getEmail());
return new ResponseEntity<>(headers, HttpStatus.NOT_FOUND);
}
}
I'm trying to migrate to RestAssuredMockMvc from regular MockMvc for a Spring Web Application, but I ran into a problem:
When trying to test against a simple resource, I get a 404. I wrote an equivalent MockMvc test as well, which succeeds.
Here are the two tests:
RestAssured:
package at.mycompany.iad.remote.internalorg.v1.controller;
import at.mycompany.iad.remote.internalorg.v1.resource.OrgProfileResource;
import at.mycompany.iad.remote.internalorg.v1.testconfig.TestConfig;
import io.restassured.module.mockmvc.RestAssuredMockMvc;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;
import static io.restassured.RestAssured.when;
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class)
public class OrgProfileControllerITRestAssured {
#Autowired
private WebApplicationContext context;
#Before
public void initRestAssured() {
RestAssuredMockMvc.webAppContextSetup(context);
// RestAssuredMockMvc.standaloneSetup(new OrgProfileResource(null)); //I tried this too, same result
}
#Test
public void getAd() throws Exception {
when()
.get("/examplepartnerid/profile")
.then()
.statusCode(HttpStatus.OK.value());
}
}
And MockMvc:
package at.mycompany.iad.remote.internalorg.v1.controller;
import at.mycompany.iad.remote.internalorg.v1.testconfig.TestConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TestConfig.class)
public class OrgProfileControllerITMockMvc {
#Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
#Before
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
#Test
public void testGet() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(
get("/examplepartnerid/profile"))
.andExpect(status().is(200)).andReturn();
}
}
And the controller being tested:
package at.mycompany.iad.remote.internalorg.v1.resource;
import at.mycompany.iad.remote.internalorg.v1.controller.OrgProfileController;
import at.mycompany.iad.remote.internalorg.v1.dto.OrgProfileDto;
import io.swagger.annotations.*;
import no.finntech.kernel.framework.exception.SystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
#RestController
#RequestMapping(value = "/{partnerId}/profile")
#Api(description = "Operations used for updating organisation services")
public class OrgProfileResource {
private final OrgProfileController controller;
#Autowired
public OrgProfileResource(OrgProfileController controller) {
this.controller = controller;
}
#RequestMapping(method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
#ApiOperation(value = "get organisation profile")
#ApiResponses({
#ApiResponse(code = 200, message = "returns organisation profile for supplied partnerId"),
#ApiResponse(code = 404, message = "no organisation found with supplied partnerId")
})
public ResponseEntity<OrgProfileDto> getOrgProfile(
#ApiParam(required = true) #PathVariable String partnerId
) throws SystemException {
OrgProfileDto orgProfile = controller.getOrgProfile(partnerId);
return ResponseEntity.status(HttpStatus.OK).body(orgProfile);
}
#RequestMapping(method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.ACCEPTED)
#ApiOperation(value = "get organisation services")
#ApiResponses({
#ApiResponse(code = 204, message = "saved organisation services for supplied partnerId"),
#ApiResponse(code = 404, message = "no organisation found with supplied partnerId")
})
public void postOrgProfileServices(
#ApiParam(required = true) #PathVariable String partnerId,
#RequestBody OrgProfileDto requestDto
) throws SystemException {
controller.saveOrgProfile(partnerId, requestDto);
}
#RequestMapping(value = "/image", method = RequestMethod.POST, headers = "content-type=multipart/form-data", consumes = "multipart/form-data")
#ApiOperation(value = "Sets an image to existing organisation")
#ApiResponses({
#ApiResponse(code = 201, message = "The reference to the image within mycompany IAd system"),
#ApiResponse(code = 404, message = "no organisation found for given org-name")
})
#ResponseStatus(HttpStatus.CREATED)
public ResponseEntity addImageToProfile(
#ApiParam(required = true) #PathVariable String partnerId,
HttpServletRequest request) throws IOException, SystemException {
controller.saveImage(partnerId, request);
return ResponseEntity.status(202).build();
}
}
I want to test my controller with the help of JUnit. I am new to this. I have written some code for this but it is not coming to my function listCard. My controller is:
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
#RequestMapping("/v1/card")
#Configuration
public class CardManagementController {
private final static Logger LOG = LoggerFactory
.getLogger(CardManagementController.class);
#Autowired
ICardService cardService;
#RequestMapping(value = "", produces = RestURIConstants.APPLICATION_JSON, method = RequestMethod.GET)
public #ResponseBody GetCardResponse getCard(
#ModelAttribute #Valid GetCardRequest request, BindingResult results)
throws RuntimeException, ValidationException {
if (results.hasErrors()) {
LOG.error("error occured occur while fetching card response");
throw new ValidationException(
"Error Occoured while validiating card request");
}
GetCardResponse response = null;
response = cardService.getCard(request);
return response;
}
#RequestMapping(value = "", produces = RestURIConstants.APPLICATION_JSON, method = RequestMethod.POST)
public #ResponseBody AddCardResponse addCard(
#ModelAttribute AddCardRequest request, BindingResult results)
throws RuntimeException, ValidationException {
if (results.hasErrors()) {
LOG.error("error occured while adding the card");
throw new ValidationException(
"Error Occoured while validiating addcard request");
}
LOG.debug("add Card with POST method");
AddCardResponse response = null;
response = cardService.addCard(request);
return response;
}
#RequestMapping(value = "", produces = RestURIConstants.APPLICATION_JSON, method = RequestMethod.DELETE)
public #ResponseBody DeleteCardResponse deleteCard(
#ModelAttribute #Valid DeleteCardRequest request,
BindingResult results) throws RuntimeException, ValidationException {
if (results.hasErrors()) {
LOG.debug("error occured while delting the card");
throw new ValidationException(
"Error Occoured while validiating delete card request");
}
DeleteCardResponse response = null;
response = cardService.deleteCard(request);
return response;
}
#RequestMapping(value = RestURIConstants.LISTCARD, produces = RestURIConstants.APPLICATION_JSON, method = RequestMethod.GET)
public #ResponseBody ListCardResponse listCard(
#ModelAttribute #Valid ListCardRequest request) throws RuntimeException, ValidationException {
ListCardResponse response = null;
response = cardService.listCards(request);
return response;
}
#ExceptionHandler({ ValidationException.class})
#ResponseBody
public CPPException handleValidationException(ValidationException ex) {
LOG.error("Exception occoured",ex);
CPPException exception = new CPPException(ex.getMessage());
exception.setStatus(500);
return exception;
}
#ExceptionHandler({RuntimeException.class})
#ResponseBody
public CPPException handleException(RuntimeException ex) {
LOG.error("Exception occoured", ex);
CPPException exception = new CPPException("Internal Server Error");
exception.setStatus(500);
return exception;
}
}
and I have written the following code for testing:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.my.cpp.controller.CardManagementController;
import com.my.cpp.request.ListCardRequest;
import com.my.cpp.service.impl.CardServiceImpl;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"classpath:/spring/application-context.xml"})
public class CardApiTest {
private MockMvc mockMvc;
//#Autowired
private CardManagementController cm=new CardManagementController();
#Autowired
private CardServiceImpl cmr;
#Before
public void setUp() throws Exception {
mockMvc= MockMvcBuilders.standaloneSetup(cm).build();
}
#Test
public void testList() throws Exception{
final ListCardRequest lr=new ListCardRequest();
this.mockMvc.perform(get("/v1/card/list?"));
}
}
First - Remove the #Configuration annotation from your controller. It doesn't belong here.
Second - Consider using Mockito while testing, since you have a service injected in your controller. Your updated test class should look something similar as below
#RunWith(MockitoJUnitRunner.class)
public class CardApiTest {
private MockMvc mockMvc;
#InjectMocks
private CardManagementController cm;
#Mock
private ICardService cardService;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(cm).build();
// Instantiate cardListRequest and cardListResponse here
when(cardService.listCards(cardListRequest)).thenReturn(cardListResponse);
}
#Test
public void testList() throws Exception{
this.mockMvc.perform(get("/v1/card/list?"));
}
}
Let know in comments if you need further info / assistance.