I want to redirect to another controller after a successful ajax call also i want to send some data that I get in the response
User Controller
#RequestMapping(method = RequestMethod.POST, value = "/user/preferences")
public #ResponseBody Map<String, List<String>> userPreferences(HttpServletRequest request) {
Map<String , List<String>> finalPlaces = new LinkedHashMap<String, List<String>>();
finalPlaces.put(entry.getKey(), new ArrayList<String>(topPlaces));
return finalPlaces;
}
Ajax Call
$(".savebutton").click(function(){
$.ajax({
url: "<c:url value='/user/preferences' />",
type: 'POST',
data:{
preferences : preferences
},
success: function(response)
{
},
error: function(xhr, ajaxOptions, thrownError) {
alert('Error');
}
});
});
when the above ajax call returns successfully I want to call a method of another controller
Places Controller
#RequestMapping(method = RequestMethod.GET, value = "/places")
public ModelAndView showRecommnededPlaces(Map<String, List<String>> recommndedPlaces) {
System.out.print(recommndedPlaces);
ModelAndView model = new ModelAndView("places");
return model;
}
is it possible to directly call the places controller action from the user controller?
Thanks
Yes, you can return "redirect:/places"; in your user controller, like:
#RequestMapping(method = RequestMethod.POST, value = "/user/preferences")
public #ResponseBody String userPreferences(HttpServletRequest request) {
Map< String, Integer> userPreferences = new HashMap< String, Integer>();
.
.
.
return "redirect:/places";
}
If you are okay about putting dependency from one controller to the next, you can actually do this:
public class UserController {
#Autowired PreferencesController prefController;
#RequestMapping(method = RequestMethod.POST, value = "/user/preferences")
public #ResponseBody Map<String, List<String>> userPreferences(HttpServletRequest request) {
Map<String , List<String>> finalPlaces = new LinkedHashMap<String, List<String>>();
finalPlaces.put(entry.getKey(), new ArrayList<String>(topPlaces));
return prefController. showRecommendedPlaces(finalPlaces);
}
}
Not saying this is good - since you will have to match the response type of your called controller appropriately, but nevertheless an approach
Related
I want to dynamically create a specific response in my controller.
#GetMapping("/test")
public ResponseEntity<?> getLanguageList() {
return ResponseEntity.ok(new Object() ??
);
}
And response on GET /test should be like that:
{
status: "OK",
info: "Hello"
}
How to do that? I don't want to create a new class for response.
Return a Map<String, Object> or Map<String, String> in the ResponseEntity. You can construct and add properties as you need in runtime to a map and it will be converted to a json structure by `ResponseEntity.ok. So, just do:
return new ResponseEntity<Map<String, Object>>(map, HttpStatus.OK) ;
I have already created Rest Endpoint in Java spring boot. It returns appropriate response when I request it via Postman. But when I use react fetch it does not show any response in browser if return is Json.
Spring boot controller:
#RestController
#RequestMapping(path = "/v1/test")
#AllArgsConstructor(onConstructor_ = {#Autowired})
public class TestController {
...
}
Below endpoint is returning appropriate response.
#GetMapping(value = "/helloWorld", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public String getHelloWorld() {
return "Hello, World1!";
}
But when I try to hit below endpoint it returns null when I make fetch request. But it returns appropriate response when I hit it via postman.
#GetMapping(value = "/testEndpoint", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public String returnTestResponse() {
HashMap<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("results", "value2");
return "{\"a\":1, \"b\":\"foo\"}";
}
Also tried returning POJO object. But still no response.
#GetMapping(value = "/testModel", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public SearchResultsModel testModel() {
this.myService.getSearchResult();
}
React fetch call:
await fetch(ALL_ARTICLES_ENDPOINT, {
mode: 'no-cors',
method: 'GET',
redirect: 'follow',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
}).then(response => {
console.log(response);
})
.then(data => {
console.log('Success:', data);
}).catch((error) => {
console.error('Error:', error);
});
Postman have couple hidden headers which are being sent with all requests.
Check Hide auto-generated headers
What you are missing in react call is is Accept header with application/json value
EDIT:
Just saw that you are returning string as json. You need to wrap it in POJO object and return it in returnTestResponse class
SECOND EDIT:
This will work. Try to implement your POJO
#GetMapping(value = "/testEndpoint", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public YourObject returnTestResponse() {
HashMap<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("results", "value2");
return new YourObject(map);
}
Issue was caused by adding mode: 'no-cors' option in fetch request. This option helped me to get rid of cors error but it means that in return I won't be able to see body and headers in chrome.
To resolve the issue I removed mode: 'no-cors' and added #CrossOrigin annotation on my spring boot controller.
The foreground sends an ID to the background through Ajax, but the background never receives it. I have been troubled by this problem for a whole day, and I really need your help.Here are my JS and Controller and error messages
$('.category-wrap').on('click', '.now .delete', function (e) {
var target = e.currentTarget;
var pc = target.dataset.id;
var pcId = {'pcId':pc};
$.confirm('sure?',function () {
$.ajax({
url: deleteUrl,
type: 'POST',
data: pcId,
contentType: 'application/json',
cache: false,
success: function (data) {
if (data.success) {
$.toast('successfully delete!');
getList();
} else {
$.toast('Delete failed!');
}
}
});
})
});
#RequestMapping(value = "/removeproductcategory", method = RequestMethod.POST)
#ResponseBody
public Map<String, Object> removeProductCategory(#RequestBody Integer pcId,
HttpServletRequest request)
{...}
image 1
image 2
you send a json request var pcId = {'pcId':pc}; and try to receive an Integer #RequestBody Integer pcId
try to define a Pojo like this
class RequestData {
public Integer pcId;
}
and modifiy controller method parameter
#RequestMapping(value = "/removeproductcategory", method = RequestMethod.POST, consumes = "application/json" )
#ResponseBody
public Map<String, Object> removeProductCategory(#RequestBody RequestData pcId,
HttpServletRequest request)
I'm trying to send "search" parameters to Spring Controller but keep getting the 400 bad request . I tried #RequestParam("personalNumber")String personalNumber but it still doesn't work, so now I'm trying to get the wrapper , can you suggest how to send wrapper info to Java controller ? (Wrapper has instances of other classes)
AngularJs
angular.extend($scope, {
obj:{
personalNumber:"",
firstName:"",
lastName:"",
dateFrom:"",
dateTo:""
},
loadCarLoan: urls.BASE_API + "user/getOnlineApplicationList",
carLoanList:[
],
});
$scope.getCarLoan = function () {
$(".loader").show();
console.log("In the angular");
$http.post($scope.loadCarLoan + $.param($scope.obj))
.success(function (response) {
console.log(response);
if(response.success){
$scope.carLoanList = response;
}
$(".loader").hide();
}).error(function () {
$(".loader").hide();
$scope.carLoanList = [];
})
};
$scope.filter = function () {
$scope.getCarLoan();
};
Java Controller :
#RequestMapping(value = "user/getOnlineApplicationList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
public #ResponseBody String getOnlineApplicationList(HttpSession session,
#RequestBody OnlineApplicationListWrapper wrapper) {
System.out.println("In the Controller Java");
HashMap<String, Object> jsonMap = new HashMap<>();
Car car = wrapper.getCar();
Loan loan = wrapper.getLoan();
CustPaymentPlan cpp = wrapper.getCpp();
NaturalPerson np = wrapper.getPerson();
jsonMap.put("success", "true");
jsonMap.put("car", car);
jsonMap.put("loan", loan);
jsonMap.put("cpp", cpp);
jsonMap.put("np", np);
System.out.println(wrapper.getCar().toString());
System.out.println(wrapper.getLoan().toString());
System.out.println(wrapper.getCpp().toString());
System.out.println(wrapper.getPerson().toString());
System.out.println("========");
System.out.println(gson.toJson(jsonMap));
return gson.toJson(jsonMap);
}
You need to change:
#RequestParam("personalNumber") String personalNumber
To:
#RequestParam(value = "personalNumber", required = false) String personalNumber
The required = false indicates to spring that the parameter can be optional.
No need to create a wrapper
I am wondering is it possible to generate ModelAndView's output programatically and not via controller's return parameter. For example:
I have the following method that returns a compiled html:
#RequestMapping(value = "/get-list", method = RequestMethod.GET, headers = BaseController.AJAX_HEADER)
public ModelAndView getList(#RequestParam(value = "page", required = true) Integer page,
#ActiveUser User activeUser) {
ModelAndView result = null;
try {
result = new ModelAndView("administration/events-log/list");
result.addObject("events", eventsLogService.getList(page, Config.RECORDS_PER_PAGE));
}
catch (Exception e) {
log(e, activeUser.getUsername());
}
return result;
}
What I want is to create something like that:
#RequestMapping(value = "/get-list", method = RequestMethod.GET, headers = BaseController.AJAX_HEADER)
public #ResponseBody HashMap<String, Object> getList(#RequestParam(value = "page", required = true) Integer page,
#ActiveUser User activeUser) {
HashMap<String, Object> json = new HashMap<String, Object>();
try {
json.put("error", 0);
ModelAndView result = new ModelAndView("administration/events-log/list");
result.addObject("events", eventsLogService.getList(page, Config.RECORDS_PER_PAGE));
json.put("content", result);
}
catch (Exception e) {
/**/
}
return json;
}
so the JSON object that will be sended back to the client will look:
{'error': 0, 'content': compiled_html}
Any thoughts? Thank you
ModelAndView has no output. It just knows the name of the view. The rendering of the view is independent of Spring MVC.
If you simply want to send JSON that contains some HTML you can put the JSON code directly on your jsp. Change your java code like that:
result = new ModelAndView("path/to/json");
result.addObject("events", eventsLogService.getList(page, Config.RECORDS_PER_PAGE));
result.addObject("html", "administration/events-log/list");
Your JSON jsp can look like this:
<%# page contentType="application/json" %>
{
"error": "0",
"content": "<jsp:include page="${html}" />"
}
Please note that this code is just for illustration. You may have adapt it to your situation. And you have to escape the included HTML to get valid JSON.