2013-12-22 3 views
2

Я пробовал использовать Tomcat 7 и Tomcat 8 RC 5, но мой JSP-компонент не является рендерингом.Servlet Spec 3.0 без рендеринга JSP включает

Я использую Spring MVC (не думаю, что это имеет значение, хотя).

My JSP выглядит следующим образом:

<jsp:include page="includes/header.jsp" /> 
It Worked! 
<jsp:include page="includes/footer.jsp" /> 

Когда страница визуализируется это выглядит следующим образом

<jsp:include page="includes/header.jsp" /> 
It Worked! 
<jsp:include page="includes/footer.jsp" /> 

В моем файле Pom Я в том числе:

<dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-beans</artifactId> 
     <version>3.2.4.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>javax.servlet</groupId> 
     <artifactId>javax.servlet-api</artifactId> 
     <version>3.0.1</version> 
    </dependency> 

Мой веб .xml выглядит следующим образом:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    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" 
    id="Blog" version="3.0"> 
<display-name>Blog</display-name> 
    <error-page> 
    <error-code>404</error-code> 
    <location>/WEB-INF/jsp/error/404.html</location> 
</error-page> 

My App Initializer выглядит следующим образом:

public class AppInitializer implements WebApplicationInitializer { 
@Override 
public void onStartup(ServletContext servletContext) throws ServletException { 
    AnnotationConfigWebApplicationContext context = new  AnnotationConfigWebApplicationContext(); 
    context.setConfigLocation("com.package.to.AppConfig"); 
    servletContext.addListener(new ContextLoaderListener(context)); 
    ServletRegistration.Dynamic servlet = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context)); 
    servlet.setLoadOnStartup(1); 
    servlet.addMapping("/*"); 
} 

Что я делаю неправильно? Почему мой объект не отображается правильно?

Я также попытался следующие с тем же результатом:

<%@ include file="includes/header.jsp" %> 
It Worked! 
<%@ include file="includes/footer.jsp" %> 

контроллер Метод:

@Controller 
public class PageController { 

@Autowired 
PageService pageService; 

@RequestMapping(value = "/*", method = RequestMethod.GET) 
public String index(HttpServletRequest request){ 
    String path = request.getRequestURI().substring(request.getContextPath().length()); 
    Page page = pageService.getPageByUrl(path); 
    if(page == null){ 
     throw new ResourceNotFoundException(); 
    } 

    return page.getTemplate().getPageTemplatePath(); 
} 

}

AppConfig

@Configuration 
@ComponentScan({"package.to.scan"}) 
@EnableTransactionManagement 
@EnableWebMvc 
@PropertySource("/${env:prod}.properties") 
@Import({DataSourceConfig.class}) 
public class AppConfig extends WebMvcConfigurerAdapter { 

@Autowired 
Environment environment; 

@Bean 
public InternalResourceViewResolver internalResourceViewResolver(){ 
    InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); 
    internalResourceViewResolver.setPrefix("/WEB-INF/jsp/"); 
    internalResourceViewResolver.setSuffix(".jsp"); 
    return internalResourceViewResolver; 
} 

@Override 
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
    configurer.enable(); 
} 

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    registry.addResourceHandler("/styles/**").addResourceLocations("/styles/"); 
    registry.addResourceHandler("/images/**").addResourceLocations("/images/"); 
    registry.addResourceHandler("/scripts/**").addResourceLocations("/scripts/"); 
} 

} 
+0

Можете ли вы показать метод контроллера, который пересылает ваш jsp? И я хотел бы видеть вашу соответствующую конфигурацию контекста. –

+0

Добавлен метод контроллера. – unknown

+0

И ваш контекст имеет «InternalResourceViewResolver» или что-то еще? –

ответ

2

Для быстрого решения, измените свой DispatcherServlet картирование до / вместо /*.

У вас есть картинка /* для вашего DispatcherServlet. Другими словами, любые неименованные RequestDispatcherforward s или include s пройдут через это же Servlet.

Так что, когда ваши InternalResourceViewResolver «s разрешен вид пытается направить, например,

/WEB-INF/jsp/somepage.jsp 

в DispatcherServlet будет выбран, чтобы обработать его. Поскольку у вас нет @Controller метод, который обрабатывает запросы на этот URL, то SimpleUrlHandlerMapping зарегистрирован

@Override 
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
    configurer.enable(); 
} 

будет использоваться. DefaultServletHandlerConfigurer регистрирует DefaultServletHttpRequestHandler, который отправляет запрос на defaultServlet.Она делает это путем приобретения defaultServlet по имени

@Override 
public void handleRequest(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 

    RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName); 
    if (rd == null) { 
     throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet '" + 
       this.defaultServletName +"'"); 
    } 
    rd.forward(request, response); 
} 

с Tomcat, как правило, это org.apache.catalina.servlets.DefaultServlet который

по умолчанию ресурсов служит сервлет для большинства веб-приложений, используемых служить статические ресурсы, такие как HTML-страницы и изображения.

Другими словами, она не обрабатывает JSP-страницы, он просто передает их непосредственно в HttpServletResponseOutputStream.

Если вместо этого, вы измените DispatcherServlet URL-отображение на /, то Servlet контейнер будет снова пройти через правила для сопоставления URL-адресов. Они описаны в документе Servlet Specification. Третий один идет

Если последний сегмент в URL-путь содержит расширение (например, .jsp), контейнер сервлетов будет пытаться соответствовать сервлет, который обрабатывает запросы для расширения. Расширение определяется как часть последнего сегмента после последнего «» характер

В этом случае, Tomcat по умолчанию будет найти org.apache.jasper.servlet.JspServlet, который сопоставлен

<servlet-mapping> 
    <servlet-name>jsp</servlet-name> 
    <url-pattern>*.jsp</url-pattern> 
    <url-pattern>*.jspx</url-pattern> 
</servlet-mapping> 

Этот URL - сопоставление матчей /WEB-INF/jsp/somepage.jsp и поэтому выбрано. JspServlet делает рендеринг jsps и так будет делать трюк.


Несколько связанных заметьте, servlet-api должно быть предусмотрено Servlet контейнера, а не ваш веб-приложений.

Изменить этот

<dependency> 
    <groupId>javax.servlet</groupId> 
    <artifactId>javax.servlet-api</artifactId> 
    <version>3.0.1</version> 
</dependency> 

к этому

<dependency> 
    <groupId>javax.servlet</groupId> 
    <artifactId>javax.servlet-api</artifactId> 
    <version>3.0.1</version> 
    <scope>provided</scope> 
</dependency> 

Независимо, если это является причиной или нет, вы должны сделать это изменение.

+0

Сделано изменение. Результат тот же. Спасибо за указатель. – unknown

+0

@ user1304051 Пожалуйста, см. Полный ответ. –