Heesun Kim
Heesun Kim

Reputation: 21

ModelAndView doesn't return data to JSP

I'm trying to send the data to JSP from Controller using ModelAndView. But it doesn't show.. What am I missing? Do I have to do something more?

This is my Controller.

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

@RestController
public class RobotpaymentController {

    @RequestMapping(value="/seikyu", method={RequestMethod.GET}, produces = MediaType.APPLICATION_JSON_VALUE)
    public ModelAndView seikyu(HttpServletRequest request) {
        RedirectView redirectView;
        ModelAndView mv;

        String seikyuId = request.getParameter("seikyuId");

        redirectView = new RedirectView("/pages/error.jsp");
        mv = new ModelAndView(redirectView);
        mv.addObject("title", "エラー");
        mv.addObject("message1", "ご連絡ください。");

        return mv;  
    }
}

And this is JSP.

<!DOCTYPE html>
<html>
<head> 
  <title></title>
  <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"/>

  <script src="/assets/js/common/jquery-3.4.1.min.js"></script>

</head>
<body style="height: auto; min-height: 100%; background:#ecf0f5;">
    <div class="wrapper" style="height: auto; min-height: 100%;">
        <header class="main-header"></header>
        <div class="content-wrapper" style="min-height: 1046px;">
            <section class="content-header"></section>
            <section class="content">
                <div class="row">
                <div class="col-md-6 col-sm-offset-2">
                    <div class="box box-default">
                        <div class="box-header with-border">
                            <i class="fa fa-warning text-red"></i>
                            <h3 class="box-title"><strong>${title}</strong></h3>
                        </div>
                        <div class="box-body">
                            <h4>${message1}</h4>
                        </div>
                    </div>
                </div>
                </div>
            </section>
        </div>
    </div>
</body>
</html>

And this is the image file. As you can see ModelAndView return parameters as querystring but it doesn't show up in JSP. image


I changed Java Code and JSP.

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

@Controller
public class RobotpaymentController {

    @RequestMapping(value="/seikyu", method={RequestMethod.GET})
    public ModelAndView seikyu(HttpServletRequest request) {
        RedirectView redirectView;
        ModelAndView mv;

        String seikyuId = request.getParameter("seikyuId");

        redirectView = new RedirectView("/pages/error.jsp");
        //redirectView.setExposeModelAttributes(false);

        mv = new ModelAndView(redirectView);
        mv.addObject("title", "エラー");
        mv.addObject("message1", "ご連絡ください。");

        return mv;  
    }
}
<!DOCTYPE html>
<html>
<head> 
  <title></title>
  <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"/>

  <script src="/assets/js/common/jquery-3.4.1.min.js"></script>

</head>
<body style="height: auto; min-height: 100%; background:#ecf0f5;">
    <div class="wrapper" style="height: auto; min-height: 100%;">
        <header class="main-header"></header>
        <div class="content-wrapper" style="min-height: 1046px;">
            <section class="content-header"></section>
            <section class="content">
                <div class="row">
                <div class="col-md-6 col-sm-offset-2">
                    <div class="box box-default">
                        <div class="box-header with-border">
                            <i class="fa fa-warning text-red"></i>
                            <h3 class="box-title"><strong><%= request.getParameter("title") %></strong></h3>
                        </div>
                        <div class="box-body">
                            <h4><%= request.getParameter("message1") %></h4>
                        </div>
                    </div>
                </div>
                </div>
            </section>
        </div>
    </div>
</body>
</html>

enter image description here

It worked but I want to use ${} instead of <%= %>. Also I didn't want to be shown query string on URL so I added line redirectView.setExposeModelAttributes(false); but this api seems to remove parameters from URL and nothing to be shown again.

Upvotes: 1

Views: 820

Answers (2)

Tomoki Sato
Tomoki Sato

Reputation: 638

To access parameters taken from a query string in jsp, you need to use param object.
You need to change your jsp like this.

<h3 class="box-title"><strong>${param.title}</strong></h3>
<h4>${param.message1}</h4>

NOTE
Your JSP and Controller should work even if you don't remove produces = MediaType.APPLICATION_JSON_VALUE and don't change @RestController to @Controller. However they do nothing when you return ModelAndView from your controller's method. So I also suggest that you remove produces = MediaType.APPLICATION_JSON_VALUE and change @RestController to @Controller.

See Also
How to get parameters from the URL with JSP


EDIT1
To avoid exposing the data to URL, I’d like to show 2 alternative solutions.

1) Use ‘forward’ instead of ‘redirect’
When your controller ‘forwards’ the request to the JSP, the HTTP request is dispatched to the JSP internally in your server(not via web browser). So you can pass the data to the JSP not exposing it to the web browser.

Your controller’s method will be something like below.

    @RequestMapping(value="/seikyu", method={RequestMethod.GET})
    public String seikyu(HttpServletRequest request. Model model) {

        String seikyuId = request.getParameter("seikyuId");
        ....
        model.addAttribute("title", "エラー");
        model.addAttribute("message1", "ご連絡ください。");

       // If you  configure ‘ViewResolver’ like `registry.jsp("/WEB-INF/",".jsp”)`
       // you can ‘forward’ the request to the /WEB-INF/redirect.jsp by returning “redirect”.
        return “redirect”;  
    }

What string you have to return from the method depends on your ViewResolver configuration and the path of the JSP.


2) Use RedirectAttributes and redirect the request to the JSP 'via' a controller.
When you put the data by using RedirectAttributes#addFlashAttribute, you can access the data in the next HTTP request. The data put by RedirectAttributes#addFlashAttribute is made accessible by Spring in the next request so you can not access the data if you redirect the request directly to the JSP. So you have to redirect it to another controller's method and make the method forward it to the JSP.

Your controller’s method will be something like below.

    @RequestMapping(value="/seikyu", method={RequestMethod.GET})
    public String seikyu(HttpServletRequest request. RedirectAttributes redirectAttributes) {

        String seikyuId = request.getParameter("seikyuId");
        ....
        redirectAttributes.addFlashAttribute("title", "エラー");
        redirectAttributes.addFlashAttribute("message1", "ご連絡ください。");

        // If your servlet-mapping is ‘/app/*’, the string to be returned is something like this.
        return “redirect:/app/fromRedirect”;  
    }

   @RequestMapping("/fromRedirect")
   public String fromRedirect(....)  {
      ....
      return "redirect";
   }

What string you have to return from the seikyu method depends on your servlet-mapping configuration. The fromRedirect method ‘forwards’ the request to the JSP like 1) example.

See Also
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
Spring Framework Documentation - Spring Web MVC - Flash Attributes

Upvotes: 1

Ananthapadmanabhan
Ananthapadmanabhan

Reputation: 6216

Try removing the produces = MediaType.APPLICATION_JSON_VALUE from your endpoint and return the ModelAndView from a normal controller instead of a RestController. A rest controller method only returns json in response and it does not resolve the view. So even if you specified a view in the ModelAndView object it won't get resolved as a result the model won't get binded to the jsp you provided.

@Controller
public class RobotpaymentController {

    @RequestMapping(value="/seikyu", method={RequestMethod.GET})
    public ModelAndView seikyu(HttpServletRequest request) {
        RedirectView redirectView;
        ModelAndView mv;

        String seikyuId = request.getParameter("seikyuId");

        redirectView = new RedirectView("/pages/error.jsp");
        mv = new ModelAndView(redirectView);
        mv.addObject("title", "エラー");
        mv.addObject("message1", "ご連絡ください。");

        return mv;  
    }
}

Upvotes: 0

Related Questions