Spring using ModelAndView addObject

孤者浪人 提交于 2019-12-23 05:27:56

问题


I am trying to display objects in a jsp page that are loaded using addObject() and returned via a controller. I am not seeing the objects in the jsp. Here is my controller:

import java.util.ArrayList;
import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.apress.pss.terrormovies.model.Movie;
import com.apress.pss.terrormovies.service.MoviesService;

@Controller
@RequestMapping("/movies")
public class MovieController {

    @Autowired
    private MoviesService moviesService;

    ... Other Mapped mehtods not shown ...

    // Respond to http://localhost:8080/movies and require login
    // Get a list of movie objects in an ArrayList and return to view
    @RequestMapping(method = RequestMethod.GET, value="/")
    public ModelAndView getAllMovies() {
        ModelAndView mv = new ModelAndView("allMovies");

        // Debug
        for (Movie movie: moviesService.getAllMovies()) {
           System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " + movie.getName());
        }

        mv.addObject("movies", moviesService.getAllMovies());
        return mv;

    }

}   

Here is my MoviesServiceImpl that implements moviesService.getAllMoivies()

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.access.prepost.PostFilter;

import com.apress.pss.terrormovies.model.Movie;

public class MoviesServiceImpl implements MoviesService {

private static final Map<String, Movie> MOVIES = new HashMap<String, Movie>();

    static {
    //System.out.println("----------------- Entering Die Hard");
    MOVIES.put("die hard", new Movie("Die Hard", "20000000"));
    // Create another movie for testing PostAuthorize in MoviesController
    //System.out.println("----------------- Entering two days in paris");
    MOVIES.put("two days in paris", new Movie("two days in paris", "1000000"));
    }

    ... Other methods not shown....

    // Allow ROLE_ADMIN to have access to movies with budget over 5000000. Other 
    // users will see only movies with budgets < 5000000
    @PreAuthorize("isFullyAuthenticated()")
    @PostFilter("hasRole('ROLE_ADMIN') or (hasRole('ROLE_USER') and T(java.lang.Integer).parseInt(filterObject.budget) < 5000000)")
    public Collection<Movie> getAllMovies() {
        return new ArrayList<Movie>(MOVIES.values());
    }
}

Here is the jsp page I am using to display the results:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="security"
uri="http://www.springframework.org/security/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Terror movies</title>
</head>
<p>Movies:</p>
<body>

<c:if test="${not empty movies}">
    <c:forEach items="${movies}" var="movie">   
        ${movie.name}<br />
    </c:forEach> 
</c:if>

</body>
</html>

Finally, here is my Movies class:

public class Movie {

    private String name;
    private String budget;

    public Movie(String name, String budget) {

        super();
        this.name = name;
        this.budget = budget;
    }

    public String getName() {
    return name;
    }

    public String getBudget() {
        return budget;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setBudget(String budget) {
        this.budget = budget;
    }

    public String toString() {
        return "Title: " + name + "; Budget: " + budget;
    }

}

When I got to the URL /movies (on localhost) I am prompted for login. When I login as ADMIN I should see both the movies added into the MOVIES Map in MoviesServiceImpl. I can see the debug in the static block load the movies. I can see the movies accessed by the debug in the MovieController.getAllMovies() method. I am correctly directed to the allMovies.jsp page, but the only thing output is "Movies:". If I remove the check around the for loop in allMovies.jsp I get the following output: Movies: ${movie.name}. There are no exceptions thrown or other errors I can see, however I don't believe I am using ModelAndView.addObject() correctly. Some help would be appreciated. Thank you in advance.

Update: If I put the following statemnt in my jsp page: <% System.out.println("jsp: movie " + pageContext.findAttribute("movies")); %> I will get the following output: "jsp: movie [Title: Die Hard; Budget: 20000000, Title: two days in paris; Budget: 1000000]" So the Object array is getting to the jsp page, I am just not accessing it correctly but don't see the error.


回答1:


Can you please check with Model.addAttribute(name, value) instead of ModelAndView.addObject(name, value)? I think you should get the same problem with the Model.addAttribute approach as well.

Please try adding the following

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

to the JSP.




回答2:


For those who may have a similar problem, the answer turned out to be with my web.xml file. This example is from the book Pro Spring Security. The author builds on previous examples to illustrate concepts. With this example, the author did not mention updating the web.xml file from its earlier versions which were using a DTD rather than an XML Schema. I had to change my web.xml from:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
...
</web-app>

To:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
...
</web-app>

The EL expressions were not being evaluated. Works fine now.




回答3:


Resolved by modifying

<web-app> 

as

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0"
  metadata-complete="true">


来源:https://stackoverflow.com/questions/21691253/spring-using-modelandview-addobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!