HTTP Status 500 – Internal Server Error org.springframework.beans.factory.BeanCreationException: - spring

Whenever i run my spring-jdbc project and i entere the url in my browser i get this HTTP error , i want to know if my mapping is wrong ,because i am not able to pinpoint the error in my code.
RestController.java
public class RestControllerTest {
#Test(timeout = 30000000)
public void testCreateRide(){
RestTemplate restTemplate=new RestTemplate();
Ride ride=new Ride();
ride.setName("Indoor run");
ride.setDuration(60);
restTemplate.put("http://localhost:8080/ride_tracker/ride",ride);
System.out.println(" "+ride);
}
#Test(timeout= 2000000)
public void testGetRide(){
RestTemplate restTemplate=new RestTemplate();
Ride ride;
ride=restTemplate.getForObject("http://localhost:8080/ride_tracker/ride/1",Ride.class);
System.out.println(" Ride name : "+ride.getName());
}
#Test(timeout=30000000)
public void testUpdateRide(){
RestTemplate restTemplate=new RestTemplate();
Ride ride;
ride=restTemplate.getForObject("http://localhost:8080/ride_tracker/ride/1",Ride.class);
ride.setDuration(ride.getDuration() + 1);
restTemplate.put("http://localhost:8080/ride_tracker/ride",ride);
System.out.println(" Ride name : "+ride.getName());
}
#Test(timeout= 2000000)
public void testBatchUpdate(){
RestTemplate restTemplate=new RestTemplate();
Ride ride;
restTemplate.getForObject("http://localhost:8080/ride_tracker/batch",Object.class);
}
#Test(timeout= 2000000)
public void testDelete(){
RestTemplate restTemplate=new RestTemplate();
restTemplate.delete("http://localhost:8080/ride_tracker/delete/5");
}
}
#Controller
public class RideController {
#Autowired
private RideService rideService;
#RequestMapping(value="/ride",method=RequestMethod.PUT)
public #ResponseBody Ride createRide(#RequestBody Ride ride){
return rideService.createRide(ride);
}
#RequestMapping(value = "/rides", method = RequestMethod.GET)
public #ResponseBody List<Ride> getRides() {
return rideService.getRides();
}
#RequestMapping(value="/ride/{id}", method = RequestMethod.GET)
public #ResponseBody Ride getRide(#PathVariable(value="id") Integer id){
return rideService.getRide(id);
}
#RequestMapping(value = "/ride",method=RequestMethod.PUT)
public #ResponseBody Ride updateRide(#RequestBody Ride ride){
return rideService.updateRide(ride);
}
#RequestMapping(value="/batch",method=RequestMethod.GET)
public #ResponseBody Object batch(){
rideService.batch();
return null;
}
#RequestMapping(value="/delete/{id}",method=RequestMethod.DELETE)
public #ResponseBody Object delete(#PathVariable(value = "id") Integer id ){
rideService.deleteRide(id);
return null;
}
}

Related

How to handle response codes in RestTemplate without catching exceptions? [Spring Boot]

I'm sending a response to another web service to create an user. If the user already exists it sends back the 409 response. I'm using RestTemplate like so:
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://friend:5000/users";
try {
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
return result;
}
catch (HttpClientErrorException ex) {
return ResponseEntity.status(ex.getRawStatusCode()).headers(ex.getResponseHeaders())
.body(ex.getResponseBodyAsString());
}
}
While catching an exception somewhat works (in the catch block i can access the status code and body), is there a way to access it without exceptions something similar like this:
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
RestTemplate restTemplate = new RestTemplate();
final String uri = "http://friend:5000/users";
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
if(result.getStatusCode()=="409"){
// do something
}
else{
// do something else
}
return result;
}
Have you been check the ExceptionHandler? When exception throws, ExceptionHandler handles it.
For example:
#ControllerAdvice()
public class CustomExceptionHandler {
private static final Logger logger = LogManager.getLogger("CustomExceptionHandler");
#ExceptionHandler(YourException.class)
public ResponseEntity handleYourException(HttpServletRequest request, YourException ex) {
return ResponseEntity.ok("");
}
#ExceptionHandler(Exception.class)
public ResponseEntity handleException(HttpServletRequest request, Exception ex) {
logExp("Exception", request, ex);
//return new ResponseEntity<>();
return null;
}
}
You can create your own custom resttemplate and define exception handler. Here is a code snippet.
#Configuration
public class CustomRestTemplate extends RestTemplate {
#Autowired
private CustomErrorHandler customErrorHandler;
#PostConstruct
public void init() {
this.setErrorHandler(customErrorHandler);
}
}
#Component
public class CustomErrorHandler implements ResponseErrorHandler {
#Override
public boolean hasError(ClientHttpResponse response) throws IOException {
if(response.getStatusCode() != "409"){
return true;
}else {
return false;
}
}
#Override
public void handleError(ClientHttpResponse response) throws IOException {
String responseBody = response.getBody();//Pls read from InputStream and create write into String
JSONObject jsonObj = new JSONObject(result);
JSONArray jsonArray = new JSONArray();
jsonObj.put("status", response.getStatusCode());
jsonObj.put("body", responseBody );
jsonArray.put(jsonObj);
responseString = jsonArray.get(0).toString();
throw new MyException(responseString );
}
}
class MyException throw RuntimeException {
public MyException (String message) {
super(message);
}
}
So, your class will changed to
#PostMapping("/todos/{toDoNoteId}/users")
public ResponseEntity <String> postUser(#RequestBody User user, #PathVariable int toDoNoteId, UriComponentsBuilder builder)throws HttpMessageNotReadableException, ParseException{
CustomRestTemplate restTemplate = new CustomRestTemplate ();
final String uri = "http://friend:5000/users";
ResponseEntity<String> result = restTemplate.postForEntity(uri, user, String.class);
return result
}

In the Spring3,How to call a another server's controller in my controller

I have 3 servers,serverA,serverB,serverC,Now in the serverC,some request from serverB is by processed,and then,I don't know what is the result(response),if it's resultA,I want give the resultA to the serverA as a request,else give the serverB.
so what I can do something in the serverC's controller,or there is something wrong in the desgin.
Please tell me what I should to do,Thanks.
This is my code.
serverA
#RestController
public class ControllerA {
#RequestMapping(value = "/methodA", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<String> methodA(#RequestBody String something) {
// some process
return null;
}
serverB
#RestController
public class ControllerB {
#RequestMapping(value = "/methodB", consumes =MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> methodB(#RequestBody String something) {
// some process
return null;
}
serverC
#RestController
public class ControllerC {
public ResponseEntity<String> methodC(#RequestBody String someReq) {
if (checkPam(someReq)) {
**// I want to call the ControllerA in serverA.**
}else {
**// I want to call the ControllerB in serverB.**
}
return null;
}
You can simply Use RestTemplate:
#RestController
public class ControllerC {
public ResponseEntity<String> methodC(#RequestBody String someReq) {
RestTemplate restTemplate = new RestTemplate();
if (checkPam(someReq)) {
String fooResourceUrl
= "http://path-to-server-a/path-to-service-a";
ResponseEntity<String> response
= restTemplate.getForEntity(fooResourceUrl , String.class);
}else {
String fooResourceUrl
= "http://path-to-server-b/path-to-service-b";
ResponseEntity<String> response
= restTemplate.getForEntity(fooResourceUrl , String.class);
}
return null;
}
As you can see, I instantiate RestTemplate object by new operator, you can also declare RestTemplate bean in your context and then autowire it in your controller class.

Throwing Custom Exception with HTTP Response From Spring Validator

I have implemented a custom Validator in Spring which is called inside an overridden Jackson de-serializer. If validation fails, I want the HTTP response code to be a 403 Forbidden as defined in my ControllerAdvice.
However, the response is always 400 Bad Request.
public class InterceptedDeserializer extends StdDeserializer<Object> implements ResolvableDeserializer
{
public InterceptedDeserializer(JsonDeserializer<?> defaultDeserializer)
{
super(Object.class);
this.defaultDeserializer = defaultDeserializer;
}
#Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, My403Exception
{
this.classFieldValidator = ServletUtils.findWebApplicationContext().getBean(ClassFieldValidator.class);
Object deserializedObject = defaultDeserializer.deserialize(jp, ctxt);
Errors errors = new BeanPropertyBindingResult(deserializedObject, deserializedObject.getClass().getName());
classFieldValidator.validate(deserializedObject, errors);
if(errors.hasErrors() || errors.hasFieldErrors()){
throw new My403Exception("No funny business");
}
return deserializedObject;
}
}
#ControllerAdvice
public class ValidationControllerAdvice {
private static final Logger log = LoggerFactory.getLogger(ValidationControllerAdvice.class);
private final StringWriter sw = new StringWriter();
#ResponseBody
#ExceptionHandler(My403Exception.class)
#ResponseStatus(HttpStatus.FORBIDDEN)
public ErrorResponse my403Exception(My403Exception e) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorCode("my403");
errorResponse.setDescription(e.getMessage());
errorResponse.setMessage(e.getMessage());
e.printStackTrace(new PrintWriter(sw));
String eStackTrace = sw.toString();
log.error("My403 error message: " + e.getMessage() + "\nException Class:" + e.getClass() + "\nStack Trace:" + eStackTrace);
return errorResponse;
}
}
#ResponseStatus(value = HttpStatus.FORBIDDEN)
public class My403Exception extends RuntimeException{
private String message;
public My403Exception(String message) {
super(message);
this.message = message;
}
public My403Exception() {
}
#Override
public String getMessage() {
return message;
}
}
#ResponseStatus(HttpStatus.CREATED)
#RequestMapping(method = RequestMethod.POST, path = "/thing")
public void createmyThing(#RequestParam(value = "thing") String thing, #RequestBody() #Valid MyThing thing) throws My403Exception {
thingService.createThing(thing);
}

Rest template giving null body and status 302

I am trying to consume a rest call in my mvc controller, however every time I do it returns a null body with http status as 302.Also I am using spring boot with spring security to get https.
I've followed code samples from here: http://websystique.com/springmvc/spring-mvc-4-restful-web-services-crud-example-resttemplate/
and Get list of JSON objects with Spring RestTemplate however none of these work
Can someone please point me in the right direction
Thank you,
REST
#RequestMapping(value = "/api/*")
#RestController
public class PostApiController {
static final Logger logger = LogManager.getLogger(PostApiController.class.getName());
private final PostService postService;
#Inject
public PostApiController(final PostService postService) {
this.postService = postService;
}
//-------------------Retrieve All Posts--------------------------------------------------------
#RequestMapping(value = "post", method = RequestMethod.GET)
public ResponseEntity<List<Post>> getAllPosts() {
List<Post> posts = postService.findAllPosts();
if(posts.isEmpty()){
return new ResponseEntity<List<Post>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
}
return new ResponseEntity<List<Post>>(posts, HttpStatus.OK);
}
}
Controller
#Controller
public class PostController {
static final Logger logger = LogManager.getLogger(PostController.class.getName());
public static final String REST_SERVICE_URI = "http://localhost:8080/api"; //"http://localhost:8080/api";
private final PostService postService;
#Inject
public PostController(final PostService postService) {
this.postService = postService;
}
#SuppressWarnings("unchecked")
#RequestMapping(value = "/getAll")
// public String create(#Valid Post post, BindingResult bindingResult, Model
// model) {
public ModelAndView getAll() {
// if (bindingResult.hasErrors()) {
// return "mvchome";
// }
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Post>> responseEntity = restTemplate.exchange(REST_SERVICE_URI+"/post",HttpMethod.GET, null, new ParameterizedTypeReference<List<Post>>() {});
// ResponseEntity<Post[]> responseEntity = restTemplate.getForEntity(REST_SERVICE_URI+"/post", Post[].class);
List<Post> postsMap = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();
// List<LinkedHashMap<String, Object>> postsMap = restTemplate.getForObject(REST_SERVICE_URI+"/post", List.class);
// String s= REST_SERVICE_URI+"/post";
// logger.info(s);
if(postsMap!=null){
for(Post map : postsMap){
logger.info("User : id="+map.getUid());
}
}else{
logger.info("No user exist----------");
}
//List<Post> postList = postService.findAllPosts();
ModelAndView mav = new ModelAndView("mvchome");
mav.addObject("postsList", postsMap);
Post newpost = new Post();
mav.addObject("post", newpost);
return mav;
}
}
***** to fix my issue I modified my code to just do a redirect on select url paths instead of "/*"
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat =
new TomcatEmbeddedServletContainerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
//used to be just collection.addPattern("/*"); now I changed it to specify which path I want it to redirect
collection.addPattern("/mvchome/*");
collection.addPattern("/home/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(createHttpConnector());
return tomcat;
}
The http status 302 is usually caused by wrong url setting.
First, make sure that public ResponseEntity<List<Post>> getAllPosts() {} method is called (just print List<Post> result inside it).
If it's called properly and you can get the return value inside public ModelAndView getAll() {}.
The problem should be the directing setting of the public ModelAndView getAll() {} method.
Check if you make something wrong in your web.xml or spring configuration. Pay attention to the configuration which redirects to views and the url mapping of your dispatcher servlet.
If public ResponseEntity<List<Post>> getAllPosts() {} is called but you can't get the return value, then it should be the issues of directing setting of the public ResponseEntity<List<Post>> getAllPosts() {} method.
Check your spring configuration and web.xml for that. The possible cause usually will be the misuse of wildcard in the configuration and web.xml, or just unnoticed wrong mapping.

Spring: Catch exception thrown from AccessDecisionManager - NOT from Controller

Using Spring (4.2.4) with MVC (4.2.4) and Security (4.0.3). I have implemented an AccessDecisionManager and from within my decide-method I am throwing an exception:
public void decide(
Authentication authentication,
Object object,
Collection<ConfigAttribute> configAttributes
) throws AccessDeniedException, InsufficientAuthenticationException {
FilterInvocation fi = (FilterInvocation) object;
String requestUrl = fi.getRequestUrl();
...
throw new SessionCompanyNotRoleTableCompanyException(1, 2);
...
throw new AccessDeniedException("Access denied!");
}
I'm not able to catch neither "SessionCompanyNotRoleTableCompanyException" nor AccessDeniedException. I've tried using a global exception handler:
#Component
#ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
#ExceptionHandler(SessionCompanyNotRoleTableCompanyException.class)
public ModelAndView sessionCompanyNotRoleTableCompany() {
log.debug("SessionCompanyNotRoleTableCompanyException captured in GlobalExceptionHandler");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
#ExceptionHandler(Exception.class)
public ModelAndView exception(ModelMap model) {
log.debug("Exception captured in GlobalExceptionHandler");
String reason = "General Exception";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
}
I've even created ExceptionResolver-classes like:
#Component
public class SessionCompanyNotRoleTableCompanyExceptionResolver implements HandlerExceptionResolver, Ordered {
private static final Logger log = LoggerFactory.getLogger(SessionCompanyNotRoleTableCompanyExceptionResolver.class);
private int order;
#Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex
) {
if (ex instanceof SessionCompanyNotRoleTableCompanyException) {
log.debug("SessionCompanyNotRoleTableCompanyException captured in SessionCompanyNotRoleTableCompanyExceptionResolver");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
return null;
}
#Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
... and have them initialized in my web-config-class like:
#Bean
public SessionCompanyNotRoleTableCompanyExceptionResolver createSessionCompanyNotRoleTableCompanyExceptionResolver() {
SessionCompanyNotRoleTableCompanyExceptionResolver resolver = new SessionCompanyNotRoleTableCompanyExceptionResolver();
resolver.setOrder(1);
return resolver;
}
These work, i.e. exceptions are captured ONLY IF they are thrown from the Controllers. But NOT from my decide-method in the AccessDecisionManager.
What and how am I supposed to implement something that can catch these outside (before) the controller?
EDIT (adding the SessionCompanyNotRoleTableCompanyException to show you its definition):
public class SessionCompanyNotRoleTableCompanyException extends RuntimeException {
private static final long serialVersionUID = 1L;
public SessionCompanyNotRoleTableCompanyException(Long contextCompanyId, Long tableId) {
super("Context companyId: " + contextCompanyId + ", tableId: " + tableId);
}
}

Resources