Liferay + JSON + AJAX - java

I have a code
#RenderMapping
public ModelAndView model(RenderRequest renderRequest, ModelMap map) {
map.put("form", form);
ModelAndView view = new ModelAndView("view", map);
PortletSession portletSession = renderRequest.getPortletSession(true);
if(portletSession != null) {
MappingJacksonJsonView v = new MappingJacksonJsonView();
view.setView(v);
view.addObject("dataListCustomer", portletSession.getAttribute("listCustomer"));
}
init(renderRequest, view);
return view;
}
I have an error:
java.lang.IllegalArgumentException: application/json is not a supported mime type
at com.liferay.portlet.MimeResponseImpl.setContentType(MimeResponseImpl.java:159)
Error is caused by view.setView(v);
How can I added listCustomer to JSON? In listCustomer I have a ModelMap
I have code:
#ResourceMapping(value="customer")
public ModelAndView customer(
ResourceRequest req,
ResourceResponse res) {
log.debug("List Customer Resource: " + context.getCustomer());
ModelAndView mav = new ModelAndView();
MappingJacksonJsonView v = new MappingJacksonJsonView();
v.setBeanName("ajaxResult");
mav.setView(v);
mav.addObject("customer", context.getCustomer());
return mav;
}
Customer is set in #ActionMapping function and it is OK.
In JSP I have:
<portlet:resourceURL escapeXml="false" id="customer" var="customer"/>
How can I call #ResourceMapping function? Because I don't see result of log.debug("List Customer Resource: " + context.getCustomer()); in logs.

For ajax (with portal) you cannot use RenderMapping (or ActionMapping), you must use ResourceMapping (and if needed ResourceRequest and ResourceResponse as method parameters).
For example, not using spring but change is trivial, see this SO answer.

Related

Redirect from Spring REST controller with parameters

I have two different Spring applications (app-one, app-two), app-one should receive a response and then redirect to app-two with some parameters. So, I have the following REST controller in app-one:
#RestController
public class RedirectController
{
#GetMapping(value = "/redirect")
public ResponseEntity<Void> redirectEndpoint(HttpServletRequest request,
RedirectAttributes redirectAttributes)
{
// Do some business logic
// Set parameters
redirectAttributes.addAttribute("attribute", "Value 1");
redirectAttributes.addFlashAttribute("flashAttribute", "Value 2");
// Redirect to success URL
String redirectURL = "http://app-two/success";
HttpHeaders headers = new HttpHeaders();
headers.setLocation(URI.create(redirectURL));
return ResponseEntity.status(HttpStatus.FOUND).headers(headers).build();
}
}
And the following REST controller in app-two:
#RestController
public class SuccessController
{
#GetMapping(value = "/success")
public ResponseEntity<Void> successEndpoint(HttpServletRequest request, Model model,
#RequestParam(value = "attribute", required = false) String attribute,
#ModelAttribute(value = "flashAttribute") String flashAttribute)
{
// Get parameters
System.out.println("attribute: " + attribute);
System.out.println("flashAttribute: " + flashAttribute);
String flashAttributeFromModelMap = (String) model.asMap().get("flashAttribute");
System.out.println("flashAttributeFromModelMap: " + flashAttributeFromModelMap);
Map<String, ?> flashMap = RequestContextUtils.getInputFlashMap(request);
if (flashMap != null)
{
String flashAttributeFromFlashMap = (String) flashMap.get("flashAttribute");
System.out.println("flashAttributeFromFlashMap: " + flashAttributeFromFlashMap);
}
// Do some business logic
return ResponseEntity.status(HttpStatus.OK).build();
}
}
I was able to redirect successfully by returning FOUND (302). But when adding attributes to RedirectAttributes (in this case attribute and flashAttribute), these attributes are not found after the redirection done (attribute gets null and flashAttribute gets empty).
I tried to get the attributes values by different ways (#RequestParam, #ModelAttribute, model.asMap().get(), and RequestContextUtils.getInputFlashMap(request).get()) but none of them gets the correct value.
What I need is to get the correct attributes' values in successEndpoint. Any suggestions on how to accomplish that?
Thanks in advance.

POST method returns wrong URL when BindingResult has errors

I have this POST method which only validates a form and returns a confirmation view if the form is validated and I want to send back to the register screen if any field is wrong. In this case if the BindingResult object has errors, the system send the user back to the form screen but the URL shown is "/registerConfirmation" which should only be in case the form has no errors.
#RequestMapping(value="/registerConfirmation", method = RequestMethod.POST)
public ModelAndView confirmRegister(#Valid #ModelAttribute("form") RegistrationForm form, BindingResult result){
logger.info("Sending registration data");
ModelAndView modelAndView = new ModelAndView();
if(result.hasErrors()){
modelAndView.setViewName("register");
modelAndView.addObject("form", form);
return modelAndView;
}
//more code here
return modelAndView;
}
I dont know what I'm missing as I have seen methods like this in many other posts. Any help??
Many thanks!!!
One way to solve your issue is to use redirect:
#RequestMapping(value="/registerConfirmation", method = RequestMethod.POST)
public String confirmRegister(#Valid #ModelAttribute("form") RegistrationForm form, BindingResult result, RedirectAttributes attr){
logger.info("Sending registration data");
if(result.hasErrors()){
attr.addFlashAttribute("org.springframework.validation.BindingResult.form", result);
attr.addFlashAttribute("form", form);
return "redirect:/register";
}
//more code here
return "redirect:/registerConfirmation";
}
and in your register GET method you should check:
#RequestMapping(value="/register", method = RequestMethod.GET)
public String showRegister(Model model) {
....
if (!model.containsAttribute("form")) {
model.addAttribute("form", new RegistrationForm());
}
.....
}
you can read more in this article
Also don't forget to create GET method with registerConfirmation value.

Java Spring Controller mapped properly, but server returns 302 instead of 200

I have following controller
#Controller
#RequestMapping("/adwords")
public class AdwordsController
{
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm(#ModelAttribute(Const.ADWORDS_COMMAND) AdwordsCommand adwordsCommand, BindingResult result)
throws HttpSessionRequiredException
{
this.checkSessionExpired();
ModelAndView mav = new ModelAndView("adwords/adwordsRequest");
if(adwordsCommand == null)
adwordsCommand = new AdwordsCommand();
User user = this.getUser();
adwordsCommand.setEmail(user.getEmail());
mav.addObject(Const.ADWORDS_COMMAND, adwordsCommand);
return mav;
}
}
That is mapped properly:
13:17:49,276 INFO RequestMappingHandlerMapping:185 - Mapped "{[/adwords],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView pl.ifirma.domeny.controller.adwords.AdwordsController.showForm(java.lang.String,org.springframework.validation.BindingResult) throws org.springframework.web.HttpSessionRequiredException
But when I type URL in browser I get 302 code and server redirects immediately to main page of application. Can anyone help? Why server does not return 200 or at least 404?
Adam
#Comments:
Such code acts exactly the same.
#Controller
#RequestMapping("/adwords")
public class AdwordsController
{
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm(#ModelAttribute(Const.ADWORDS_COMMAND) AdwordsCommand adwordsCommand, BindingResult result)
{
ModelAndView mav = new ModelAndView("adwords/adwordsRequest");
if(adwordsCommand == null)
adwordsCommand = new AdwordsCommand();
User user = this.getUser();
adwordsCommand.setEmail(user.getEmail());
mav.addObject(Const.ADWORDS_COMMAND, adwordsCommand);
return mav;
}
}
I wonder if this weird redirection could be caused by some spring configuration, but where to check it? And it is only place in project where problem occurs.
Solved. There was a hidden redirect in a view...

How to send data from controller to jsp in spring 3.0

I'm trying to send data to jsp but its not working
public class LoginPageController extends SimpleFormController
{
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws ServletException
{
Loginpage lcmd=(Loginpage)command;
System.out.println("This is LOGIN PAGE");
System.out.println(lcmd.getUserName());
System.out.println(lcmd.getPassWord());
request.setAttribute("MSG","Thank u"); //This code not doing anything.
return new ModelAndView(new RedirectView("Login.jlc"));
}
}
You are changing the request object, that will indeed do nothing.
What you want is add a variable to the Model. So here's how you can do it:
Instead of:
request.setAttribute("MSG","Thank u"); //This code not doing anything.
return new ModelAndView(new RedirectView("Login.jlc"));
Try this:
Map<String, Object> model = new HashMap<String, Object>();
model.put("MSG", "Thank u");
return new ModelAndView(new RedirectView("Login.jlc"), model); // <-- notice this
This will enable you to access that "Thank u" value through the expression ${model.MSG} and others, if you add them to the model map.

Spring controller(A).method invoked controller(B).method but finds empty Model

LoginFormController-->Post is invoked after the form is submitted/posted. At the end, it invokes another Controller called LandingFormController-->loadForm.
Well, in the loadForm the values in the Model seems to be empty. Is there a way I can persist a Bean in session or request and get it in the loadForm method? Bonus points: if you could point to some documents to refer :)
Thanks
#Controller
#RequestMapping(value="/login")
public class LoginFormController {
#RequestMapping(method=RequestMethod.POST)
public ModelAndView post(#ModelAttribute User user, BindingResult result, SessionStatus status) {
logger.info("post");
new ReceiptUserValidator().validate(user, result);
if (result.hasErrors()) {
return new ModelAndView("login");
}
else {
logger.info("Email Id: " + user.getEmailId());
//status.setComplete();
Map<String, Object> model = new HashMap<String, Object>();
model.put("userId", user.getEmailId());
model.put("now", new Date().toString());
return new ModelAndView("redirect:/landing.htm", "model", model);
}
}
Controller B below that gets called
#Controller
#RequestMapping(value="/landing")
public class LandingFormController {
protected final Log logger = LogFactory.getLog(getClass());
#RequestMapping(method=RequestMethod.GET)
public String loadForm(Model model) {
logger.info("LandingFormController loadForm: " + model.asMap().keySet());
return "landing";
}
}
The code is performing a redirect which causes the properties placed in the model to be lost. Use flash attributes to pass the attributes to the next controller.
Flash attributes provide a way for one request to store attributes
intended for use in another. This is most commonly needed when
redirecting — for example, the Post/Redirect/Get pattern. Flash
attributes are saved temporarily before the redirect (typically in the
session) to be made available to the request after the redirect and
removed immediately.
LoginFormController
#Controller
#RequestMapping(value="/login")
public class LoginFormController {
#RequestMapping(method=RequestMethod.POST)
public ModelAndView post(#ModelAttribute User user, BindingResult result,
SessionStatus status, final RedirectAttributes redirectAttrs) {
logger.info("post");
new ReceiptUserValidator().validate(user, result);
if (result.hasErrors()) {
return new ModelAndView("login");
}
else {
logger.info("Email Id: " + user.getEmailId());
//status.setComplete();
redirectAttrs.addFlashAttribute("userId", user.getEmailId());
redirectAttrs.addFlashAttribute("now", new Date().toString());
return new ModelAndView("redirect:/landing.htm", "model", model);
}
}
Documentation
As an alternative solution you could simply not perform a redirect from the controller.
Appending retrieving solution.
Modify the loadForm
public String loadForm(#ModelAttribute("user") User user) {
logger.info("LandingFormController loadForm: " + user.getEmailId());
return "landing";
}

Categories

Resources