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

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.

Related

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

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;
}
}

RestTemplate get with body

How to make get with body using rest template?
Based on question from: POST request via RestTemplate in JSON, I tried make GET with body via HttpEntity (just check if it is possible), but
it failed receiving:
Required request body is missing
For HttpMethod.POST: localhost:8080/test/post body is added correctly, but for
HttpMethod.GET localhost:8080/test/get it is not mapped.
My code is, as below:
#RestController
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private final RestTemplate restTemplate = new RestTemplate();
#GetMapping("/test/{api}")
public SomeObject test(#PathVariable("api") String api) {
String input = "{\"value\":\"ok\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(input, headers);
HttpMethod method = "get".equals(api) ? HttpMethod.GET : HttpMethod.POST;
String url = "http://localhost:8080/" + api;
return restTemplate.exchange(url, method, entity, SomeObject.class).getBody();
}
#GetMapping("/get")
public SomeObject getTestApi(#RequestBody(required = false) SomeObject someObject) {
return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
}
#PostMapping("/post")
public SomeObject postTestApi(#RequestBody(required = false) SomeObject someObject) {
return new SomeObject() {{ setValue(someObject != null ? "ok" : "error"); }};
}
#Data
public static class SomeObject {
private String value;
}
}
Here is the repo with full example: https://gitlab.com/bartekwichowski/git-with-body
I wonder, what is wrong with code?
Also accorging to: HTTP GET with request body
GET with body is possible, but just not good practice.
I found this can't remeber where. Not a good practice, but if in your enviroment you have no other chance:
private static final class HttpComponentsClientHttpRequestWithBodyFactory extends HttpComponentsClientHttpRequestFactory {
#Override
protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
if (httpMethod == HttpMethod.GET) {
return new HttpGetRequestWithEntity(uri);
}
return super.createHttpUriRequest(httpMethod, uri);
}
}
private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
public HttpGetRequestWithEntity(final URI uri) {
super.setURI(uri);
}
#Override
public String getMethod() {
return HttpMethod.GET.name();
}
}
and when you get your restTemplate object
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestWithBodyFactory());
i had the same issue with RestTemplate and GET.
Tried to switch to Unirest but that also did not allow to use body with GET method.
Changing GET to POST is successful.
Making a call from postman after deploying in Liberty works fine and body did get accepted and expected response is generated.
i believe its something with the embedded tomcat server used.

How to map request contains File and data in Rest service using #RestController with HttpEntity<class> as input parameter

Please see below code where i want to send request having file and other json data which will be in a single java class:
My Class is(used lombok):
#Data
public class CustomFileUploadSearch {
private Long selectedId;
private MultipartFile file;
}
#RequestMapping(method = RequestMethod.POST, path = "/rest/GIER/testFileData",
consumes = {"multipart/form-data"}, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity bulkActivateInactivate(HttpEntity<CustomFileUploadSearch> entity, HttpServletRequest request) {
CustomFileUploadSearch cfuSearch = entity.getBody();
}
I am not able to reach into this method.
Please help me so that it has already taken 1 day.
Thanks in advance.
#RestController
public class ChassisInventoryRest {
#SuppressWarnings("rawtypes")
#RequestMapping(method = RequestMethod.POST, path = "/rest/GIER/testFileData",
consumes = {"multipart/form-data"}, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity bulkActivateInactivate(HttpEntity<CustomFileUploadSearch> entity, HttpServletRequest request) {
CustomFileUploadSearch cfuSearch = entity.getBody();
System.out.println("cfuSearch.getSelectedId():"+cfuSearch.getSelectedId());
System.out.println("cfuSearch.getFile():"+cfuSearch.getFile());
return new ResponseEntity<Map<String, Object>>( new HashMap<String, Object>(), HttpStatus.OK);
}
}
public class CustomFileUploadSearch {
private Long selectedId;
private MultipartFile file;
public Long getSelectedId() {
return selectedId;
}
public void setSelectedId(Long selectedId) {
this.selectedId = selectedId;
}
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
}
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity bulkActivateInactivate(CustomFileUploadSearch entity, HttpServletRequest request) {
System.out.println(entity.getSelectedId());
System.out.println(entity.getFile());
}
You can explicitly get MultipartFile as request input parameter in RestController.
#RestController
public class ChassisInventoryRest {
#PostMapping(path = "/rest/GIER/testFileData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity bulkActivateInactivate(#RequestParam MultipartFile file, #RequestParam Long selectedId) {
//parameterized constructor
CustomFileUploadSearch cfuSearch = new CustomFileUploadSearch(selectedId, file);
return new ResponseEntity<Map<String, Object>>( new HashMap<String, Object>(), HttpStatus.OK);
}
}

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.

localhost:8080/ returns status 404 - Spring

This is my code:
#Controller
#RequestMapping("/")
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As I understand when I send request to localhost:8080/ it should open localhost:8080/merchants, but it is not working. Anyone has any suggestions?
Your showMerchantsList method will be called when you send request to localhost:8080/merchants. And this method will you redirect again localhost:8080/merchants. But if you want send request as localhost:8080/ and direct you to localhost:8080/merchants, then you should create another method as this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsListWithoutRequestMapping() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
This method will redirect you to localhost:8080/merchants, when you called localhost:8080/
Normal way you should use
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As i understand your requirement silly way:
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView model=new ModelAndView("redirect:/merchants");
return model;
}
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
Note: Because / always denotes to root.

Resources