Настройте FacesServlet <url-pattern>, чтобы избавиться от расширения.xhtml.
Я имею Login.xhtml
а также Home.xhtml
, Я настроил шаблон URL в web.xml
следующее
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Login.xhtml</welcome-file>
</welcome-file-list>
Когда я запускаю весь проект, страница входа URL
это так http://localhost:8080/fran/Login.xhtml
, Вот fran
это название моего проекта..
Тем не менее, я хотел бы, чтобы это было http://localhost:8080/fran/Login/
вместо http://localhost:8080/fran/Login.xhtml
,
Как мне этого добиться? Можно ли настроить <url-pattern>
за каждую страницу, чтобы избавиться от .xhtml
расширение?
решаемая
Как BalusC упомянул ниже в комментарии... OmniFaces FacesViews - это круто. Вот шаги, которые я сделал:
- Место
omnifaces-1.5.jar
в/WEB-INF/lib
папка. Добавьте ниже код для
web.xml
:<context-param> <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name> <param-value>/*.xhtml</param-value> </context-param>
Вот и все в конфигурации. Работает на отлично.
3 ответа
Если ваша единственная причина состоит в том, чтобы избавиться от .xhtml
расширение, то есть различные способы в зависимости от версии JSF, которую вы используете.
JSF 2.3+
JSF 2.3 предлагает новый API для сбора всех представлений: ViewHandler#getViews()
, Объедините это с ServletRegistration#addMapping()
в ServletContextListener
как ниже.
@FacesConfig
@WebListener
public class ApplicationConfig implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
addExtensionLessMappings(event.getServletContext(), FacesContext.getCurrentInstance());
}
private void addExtensionLessMappings(ServletContext servletContext, FacesContext facesContext) {
servletContext
.getServletRegistrations().values().stream()
.filter(servlet -> servlet.getClassName().equals(FacesServlet.class.getName()))
.findAny()
.ifPresent(facesServlet -> facesContext
.getApplication()
.getViewHandler()
.getViews(facesContext, "/", ViewVisitOption.RETURN_AS_MINIMAL_IMPLICIT_OUTCOME)
.forEach(view -> facesServlet.addMapping(view))
);
}
}
По сути, это единственный вкладчик. Источник: Полное руководство по JSF.
JSF 2.2-
Используйте OmniFaces FacesViews. Он предлагает способ нулевой конфигурации для достижения этого путем размещения файлов просмотра в /WEB-INF/faces-views/
папка. В противном случае, если вы намереваетесь не изменять структуру своего проекта и хотите сохранить файлы представления в обычном месте и при этом использовать URL-адреса без расширений, добавьте следующий параметр контекста:
<context-param>
<param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
<param-value>/*.xhtml</param-value>
</context-param>
В случае, если вы не хотите использовать OmniFaces, а хотите самостоятельно создать свой собственный, просто посмотрите на исходный код OmniFaces. Это открытый исходный код под лицензией Apache 2.0. Это только не вкладчик.
Взгляните на симпатичные лица: красивые URL-адреса для JavaServer Faces,
Посмотрите на 2. Создайте пример pretty-config.xml на главной странице
И взгляните на Главу 2. Начало работы
Просто небольшое дополнение к мистеру. @balusc отличный ответ о MyFaces в JSF 2.3 ... (Редактировать: не совсем дополнение, поскольку нельзя дополнять то, что завершено, а просто обходной путь для пользователей tomcat/tomee, чтобы справиться с этой ошибкой tomcat).
Используя MyFaces 2.3.6, я получил исключение, говорящее о спецификации сервлета и ServletContextListener:
java.lang.UnsupportedOperationException: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with @WebListener
После стека я увидел эту строку:
at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:103)
И после добавления этого прослушивателя в web.xml все заработало нормально:
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>