java spring mvc 转发到 jsp

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5032558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:07:10  来源:igfitidea点击:

spring mvc forward to jsp

javaservletsspring-mvc

提问by jerluc

I currently have my web.xml configured to catch 404s and send them to my spring controller which will perform a search given the original URL request.

我目前将 web.xml 配置为捕获 404 并将它们发送到我的 spring 控制器,该控制器将根据原始 URL 请求执行搜索。

The functionality is all there as far as the catch and search go, however the trouble begins to arise when I try to return a view.

就捕获和搜索而言,功能就在那里,但是当我尝试返回视图时,麻烦就开始出现了。

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="jsp" value="text/html" />
        </map>
    </property>

    <property name="defaultContentType" value="application/json" />
    <property name="favorPathExtension" value="true" />

    <property name="viewResolvers">
        <list>
            <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
            <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/jsp/" />
                <property name="suffix" value="" />
            </bean>
        </list>
    </property>
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingHymansonJsonView" />
        </list>
    </property>
    <property name="ignoreAcceptHeader" value="true" />
</bean>

This is a snippet from my MVC config file.

这是我的 MVC 配置文件中的一个片段。

The problem lies in resolving the view's path to the /WEB-INF/jsp/directory. Using a logger in my JBoss setup, I can see that when I test this search controller by going to a non-existent page, the following occurs:

问题在于解析视图的/WEB-INF/jsp/目录路径。在我的 JBoss 设置中使用记录器,我可以看到当我通过转到一个不存在的页面来测试这个搜索控制器时,会发生以下情况:

  1. Server can't find the request

  2. Request is sent to 404 error page (in this case my search controller)

  3. Search controller performs search

  4. Search controller returns view name (for this illustration, we'll assume test.jspis returned)

  5. Based off of server logger, I can see that org.springframework.web.servlet.view.JstlViewis initialized once my search controller returns the view name (so I can assume it is being picked up correctly by the InternalResourceViewResolver)

  6. Server attempts to return content to browser resulting in a 404!

  1. 服务器找不到请求

  2. 请求被发送到 404 错误页面(在这种情况下我的搜索控制器)

  3. 搜索控制器执行搜索

  4. 搜索控制器返回视图名称(对于本例,我们假设test.jsp返回)

  5. 基于服务器记录器,我可以看到,org.springframework.web.servlet.view.JstlView一旦我的搜索控制器返回视图名称,它就会被初始化(所以我可以假设它被正确地拾取InternalResourceViewResolver

  6. 服务器尝试将内容返回到浏览器导致 404!

A couple things confuse me about this:

有几件事让我对此感到困惑:

  1. I'm not 100% sure why this isn't resolving when test.jspclearly exists under the /WEB-INF/jsp/directory.

  2. Even if there was some other problem, why would this result in a 404? Shouldn't a 404 error page that results in another 404 theoretically create an infinite loop?

  1. 我不是 100% 确定为什么当目录test.jsp下明确存在时这不能解决/WEB-INF/jsp/

  2. 即使有其他问题,为什么会导致 404?理论上导致另一个 404 的 404 错误页面不应该创建无限循环吗?

Thanks for any help or pointers!

感谢您的帮助或指点!

Controller class [incomplete]:

控制器类[不完整]:

@Controller
public class SiteMapController {

//--------------------------------------------------------------------------------------        
@Autowired(required=true)   
private SearchService search;

@Autowired(required=true)
private CatalogService catalog; 
//--------------------------------------------------------------------------------------

@RequestMapping(value = "/sitemap", method = RequestMethod.GET)
public String sitemap (HttpServletRequest request, HttpServletResponse response) {  
    String forwardPath = "";
    try {
        long startTime = System.nanoTime() / 1000000;
        String pathQuery = (String) request.getAttribute("javax.servlet.error.request_uri");

        Scanner pathScanner = new Scanner(pathQuery).useDelimiter("\/");
        String context = pathScanner.next();
        List<ProductLightDTO> results = new ArrayList<ProductLightDTO>();
        StringBuilder query = new StringBuilder();
        String currentValue;
        while (pathScanner.hasNext()) {
            currentValue = pathScanner.next().toLowerCase();
            System.out.println(currentValue);
            if (query.length() > 0)
                query.append(" AND ");
            if (currentValue.contains("-")) {
                query.append("\"");
                query.append(currentValue.replace("-", " "));
                query.append("\"");
            }
            else {
                query.append(currentValue + "*");
            }
        }       

        //results.addAll(this.doSearch(query.toString()));

        System.out.println("Request: " + pathQuery);
        System.out.println("Built Query:" + query.toString());
        //System.out.println("Result size: " + results.size());     
        long totalTime = (System.nanoTime() / 1000000) - startTime;
        System.out.println("Total TTP: " + totalTime + "ms");

        if (results == null || results.size() == 0) {
            forwardPath = "home.jsp";
        }
        else if (results.size() == 1) {
            forwardPath = "product.jsp";
        }
        else {
            forwardPath = "category.jsp";
        }

    }
    catch (Exception ex) {
        System.err.println(ex);
    }

    System.out.println("Returning view: " + forwardPath);
    return forwardPath;
}
}

回答by jerluc

1 . I'm not 100% sure why this isn't resolving when test.jsp clearly exists under the /WEB-INF/jsp/ directory.

1 . 当 test.jsp 明确存在于 /WEB-INF/jsp/ 目录下时,我不是 100% 确定为什么这不能解决。

This is because you did configure your view resolver with suffix = ""so the file must be named test(no extension).

这是因为您确实配置了视图解析器,suffix = ""因此必须命名文件test(无扩展名)。

2 . Even if there was some other problem, why would this result in a 404? Shouldn't a 404 error page that results in another 404 theoretically create an infinite loop?

2 . 即使有其他问题,为什么会导致 404?理论上导致另一个 404 的 404 错误页面不应该创建无限循环吗?

I'm pretty sure this's the result of some protection against the infinite redirect loop in spring MVC.

我很确定这是针对 spring MVC 中的无限重定向循环的一些保护的结果。

Note:in controllers, spring expect a view name as a result so testnot test.jsp(or better, use ModelAndView)

注意:在控制器中,spring 期望一个视图名称作为结果所以test不是test.jsp(或者更好,使用ModelAndView

回答by gigadot

I am posting this as answer because it is too long but it is probably not an answer.

我将此作为答案发布,因为它太长了,但它可能不是答案。

http://localhost:8080/webapp/servlet-mapping-url/controller-mapping/method-mapping

if your controller's method which handles the request does not return a view name string or a view object or write directly to output stream, spring dispatcher should resolve the view name to /WEB-INF/jsp/controller-mapping/method-mapping.jsp

如果处理请求的控制器方法没有返回视图名称字符串或视图对象或直接写入输出流,则 spring 调度程序应将视图名称解析为 /WEB-INF/jsp/controller-mapping/method-mapping.jsp

This means the jsp must be under a folder, named /WEB-INF/jsp/controller-mapping/. However, if a view name or view object is return by the controller method, spring dispatcher will uses that instead.

这意味着 jsp 必须位于名为 /WEB-INF/jsp/controller-mapping/. 但是,如果控制器方法返回视图名称或视图对象,则 spring 调度程序将使用它。

Ther are other many possible mapping combination but this is the most common one. If you could show your controller class, it will be easier.

还有其他许多可能的映射组合,但这是最常见的一种。如果你能展示你的控制器类,它会更容易。

Update

更新

If you are using DefaultAnnotationHandlerMapping, you should always annotated your class with @RequestMapping(value = "/mapping-string"). Otherwise spring dispatcher will try to pick it up when nothing else is matched.

如果您使用的是DefaultAnnotationHandlerMapping,则应始终使用@RequestMapping(value = "/mapping-string"). 否则 spring 调度程序将在没有其他匹配项时尝试将其捡起。

Since the controller is mapped, you will have to change the method mapping to value = {"", "/"}

由于控制器已映射,因此您必须将方法映射更改为 value = {"", "/"}

For the returning view name, you don't need to put .jsp.

对于返回的视图名称,您不需要将.jsp.

If the returning view name is homethen the spring dispatcher will resolve to /WEB-INF/jsp/home.jsp

如果返回的视图名称是home那么 spring 调度程序将解析为/WEB-INF/jsp/home.jsp

If the returning view name is path/homethen the spring dispatcher will resolve to /WEB-INF/jsp/path/home.jsp

如果返回的视图名称是path/home那么 spring 调度程序将解析为/WEB-INF/jsp/path/home.jsp

P.S. You used a word forwardPath but it isn't really a forward. It is just a view name.

PS 您使用了一个词 forwardPath 但它不是真正的转发。它只是一个视图名称。

@Controller
@RequestMapping(value = "/sitemap")
public class SiteMapController {

    @RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
    public String sitemap (HttpServletRequest request, HttpServletResponse response) {  
            ...
            if (results == null || results.size() == 0) {
                forwardPath = "home";
            }
            else if (results.size() == 1) {
                forwardPath = "product";
            }
            else {
                forwardPath = "category";
            }
            ...
        return forwardPath;
    }
}

回答by DzianisH

Try to set order for your ViewResolver. For Example:

尝试为您的 ViewResolver 设置顺序。例如:

@Bean
public ViewResolver getViewResolver(){
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setViewClass(JstlView.class);
  resolver.setPrefix("/WEB-INF/jsp/");
  resolver.setSuffix(".jsp");
  resolver.setOrder(1);
  return resolver;
}