JAVA-3529 Move spring-mvc-views module

This commit is contained in:
mikr
2020-12-29 22:31:40 +01:00
parent 06160c001d
commit 70bb63b8c6
33 changed files with 2 additions and 3 deletions

View File

@@ -0,0 +1,4 @@
### Relevant Articles:
- [Spring MVC Themes](https://www.baeldung.com/spring-mvc-themes)
- [Apache Tiles Integration with Spring MVC](https://www.baeldung.com/spring-mvc-apache-tiles)

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-mvc-views</artifactId>
<packaging>war</packaging>
<name>spring-mvc-views</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-spring-5</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>parent-spring-5/pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${javax.servlet.jsp-api.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.data.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${apache-tiles.version}</version>
</dependency>
</dependencies>
<build>
<finalName>spring-mvc-views</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>spring-mvc-views</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
<outputDirectory>${deploy-path}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.8</java.version>
<javax.servlet.jsp-api.version>2.3.3</javax.servlet.jsp-api.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version>
<spring.version>5.2.1.RELEASE</spring.version>
<spring.security.version>5.2.1.RELEASE</spring.security.version>
<spring.data.version>2.2.2.RELEASE</spring.data.version>
<cglib.version>2.2.2</cglib.version>
<hsqldb.version>2.5.0</hsqldb.version>
<hibernate.version>5.4.9.Final</hibernate.version>
<deploy-path>enter-location-of-server</deploy-path>
<apache-tiles.version>3.0.8</apache-tiles.version>
</properties>
</project>

View File

@@ -0,0 +1,44 @@
package com.baeldung.themes.config;
import org.springframework.context.annotation.Bean;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@EnableJpaRepositories(basePackages = "com.baeldung")
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL)
.addScripts("db/sql/create-db.sql", "db/sql/insert-data.sql")
.build();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.baeldung.themes.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return em;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}

View File

@@ -0,0 +1,6 @@
package com.baeldung.themes.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class InitSecurity extends AbstractSecurityWebApplicationInitializer {
}

View File

@@ -0,0 +1,56 @@
package com.baeldung.themes.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.passwordEncoder(passwordEncoder())
.dataSource(dataSource);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/anonymous*").anonymous()
.antMatchers("/login*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout()
.logoutUrl("/logout.do")
.invalidateHttpSession(true)
.clearAuthentication(true);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/themes/**");
}
}

View File

@@ -0,0 +1,53 @@
package com.baeldung.themes.config;
import com.baeldung.themes.resolver.UserPreferenceThemeResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.context.support.ResourceBundleThemeSource;
import org.springframework.web.servlet.ThemeResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
@Configuration
@ComponentScan(basePackages="com.baeldung")
@EnableWebMvc
public class ThemeMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/themes/**").addResourceLocations("classpath:/themes/");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(themeChangeInterceptor());
}
@Bean
public ThemeChangeInterceptor themeChangeInterceptor() {
ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor();
interceptor.setParamName("theme");
return interceptor;
}
@Bean
public ResourceBundleThemeSource resourceBundleThemeSource() {
ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
themeSource.setFallbackToSystemLocale(true);
return themeSource;
}
@Bean
public ThemeResolver themeResolver() {
UserPreferenceThemeResolver themeResolver = new UserPreferenceThemeResolver();
themeResolver.setDefaultThemeName("light");
return themeResolver;
}
@Override
public void configureViewResolvers(ViewResolverRegistry resolverRegistry) {
resolverRegistry.jsp();
}
}

View File

@@ -0,0 +1,47 @@
package com.baeldung.themes.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.baeldung.themes")
public class TilesApplicationConfiguration implements WebMvcConfigurer {
/**
* Configure TilesConfigurer.
*/
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/views/**/tiles.xml" });
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}
/**
* Configure ViewResolvers to deliver views.
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
TilesViewResolver viewResolver = new TilesViewResolver();
registry.viewResolver(viewResolver);
}
/**
* Configure ResourceHandlers to serve static resources
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}

View File

@@ -0,0 +1,29 @@
package com.baeldung.themes.config;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class WebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(javax.servlet.ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(DataSourceConfig.class);
context.register(ThemeMVCConfig.class);
//context.register(TilesApplicationConfiguration.class);
servletContext.addListener(new ContextLoaderListener(context));
servletContext.setInitParameter("spring.profiles.active", "database");
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}

View File

@@ -0,0 +1,13 @@
package com.baeldung.themes.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class AppController {
@RequestMapping("/")
public String home() {
return "index";
}
}

View File

@@ -0,0 +1,26 @@
package com.baeldung.themes.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/")
public class TilesController {
@RequestMapping(value = { "/" }, method = RequestMethod.GET)
public String homePage(ModelMap model) {
return "home";
}
@RequestMapping(value = { "/apachetiles" }, method = RequestMethod.GET)
public String productsPage(ModelMap model) {
return "apachetiles";
}
@RequestMapping(value = { "/springmvc" }, method = RequestMethod.GET)
public String contactUsPage(ModelMap model) {
return "springmvc";
}
}

View File

@@ -0,0 +1,30 @@
package com.baeldung.themes.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "preferences")
public class UserPreference {
@Id
private String username;
private String theme;
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@@ -0,0 +1,7 @@
package com.baeldung.themes.repository;
import com.baeldung.themes.domain.UserPreference;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface UserPreferenceRepository extends PagingAndSortingRepository<UserPreference, String> {
}

View File

@@ -0,0 +1,74 @@
package com.baeldung.themes.resolver;
import com.baeldung.themes.domain.UserPreference;
import com.baeldung.themes.repository.UserPreferenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ThemeResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
public class UserPreferenceThemeResolver implements ThemeResolver {
public static final String THEME_REQUEST_ATTRIBUTE_NAME = UserPreferenceThemeResolver.class.getName() + ".THEME";
@Autowired(required = false)
Authentication authentication;
@Autowired
UserPreferenceRepository userPreferenceRepository;
private String defaultThemeName;
public String getDefaultThemeName() {
return defaultThemeName;
}
public void setDefaultThemeName(String defaultThemeName) {
this.defaultThemeName = defaultThemeName;
}
@Override
public String resolveThemeName(HttpServletRequest request) {
String themeName = findThemeFromRequest(request).orElse(findUserPreferredTheme().orElse(getDefaultThemeName()));
request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, themeName);
return themeName;
}
private Optional<String> findUserPreferredTheme() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
UserPreference userPreference = getUserPreference(authentication).orElse(new UserPreference());
return Optional.ofNullable(userPreference.getTheme());
}
private Optional<String> findThemeFromRequest(HttpServletRequest request) {
return Optional.ofNullable((String) request.getAttribute(THEME_REQUEST_ATTRIBUTE_NAME));
}
private Optional<UserPreference> getUserPreference(Authentication authentication) {
return isAuthenticated(authentication) ? userPreferenceRepository.findById(((User) authentication.getPrincipal()).getUsername()) : Optional.empty();
}
private boolean isAuthenticated(Authentication authentication) {
return authentication != null && authentication.isAuthenticated();
}
@Override
public void setThemeName(HttpServletRequest request, HttpServletResponse response, String theme) {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (isAuthenticated(authentication)) {
request.setAttribute(THEME_REQUEST_ATTRIBUTE_NAME, theme);
UserPreference userPreference = getUserPreference(authentication).orElse(new UserPreference());
userPreference.setUsername(((User) authentication.getPrincipal()).getUsername());
userPreference.setTheme(StringUtils.hasText(theme) ? theme : null);
userPreferenceRepository.save(userPreference);
}
}
}

View File

@@ -0,0 +1,2 @@
styleSheet=themes/black.css
background=black

View File

@@ -0,0 +1,2 @@
styleSheet=themes/black.css
background=black

View File

@@ -0,0 +1,17 @@
create table users (
username varchar(50) not null primary key,
password varchar(256) not null,
enabled boolean not null
);
create table authorities (
username varchar(50) not null,
authority varchar(50) not null
);
create table preferences (
username varchar(50) not null,
theme varchar(50)
);

View File

@@ -0,0 +1,6 @@
insert into users values('john', '$2a$10$cjcbIX/aLe12PpGZ.vQfweLiB7K1QTC5enTk3oD0deCMdtj2Sx.im', 1);
insert into users values('admin', '$2a$10$cjcbIX/aLe12PpGZ.vQfweLiB7K1QTC5enTk3oD0deCMdtj2Sx.im', 1);
insert into authorities values('john', 'USER');
insert into authorities values('admin', 'USER');
insert into authorities values('admin', 'ADMIN');

View File

@@ -0,0 +1,2 @@
styleSheet=themes/white.css
background=black

View File

@@ -0,0 +1,2 @@
styleSheet=themes/white.css
background=black

View File

@@ -0,0 +1,8 @@
body {
justify-content : center;
background-color : black;
color : white;
text-align : center;
margin-left : 15%;
margin-right : 15%;
}

View File

@@ -0,0 +1,8 @@
body {
justify-content : center;
background-color : white;
color : black;
text-align : center;
margin-left : 15%;
margin-right : 15%;
}

View File

@@ -0,0 +1,46 @@
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<spring:theme code='styleSheet'/>"/>
<title>Themed Application</title>
</head>
<body>
<header>
<h1>Themed Application</h1>
<hr />
</header>
<section>
<h2>Spring MVC Theme Demo</h2>
<security:authorize access="isAuthenticated()">
<h4>User : <security:authentication property="principal.username" /></h4>
</security:authorize>
<form action="<c:url value='/'/>" method="POST" name="themeChangeForm" id="themeChangeForm">
<div>
<h4>
Change Theme
</h4>
</div>
<select id="theme" name="theme" onChange="submitForm()">
<option value="">Reset</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</form>
</section>
<section>
<form action="<c:url value='/logout.do'/>" method="POST" name="logoutForm">
<button type="submit" name="submit">Sign Out</button>
</form>
</section>
<script>
function submitForm() {
document.themeChangeForm.submit();
}
</script>
</body>
</html>

View File

@@ -0,0 +1,12 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Apache Tiles</title>
</head>
<body>
<h2>Tiles with Spring MVC Demo</h2>
</body>
</html>

View File

@@ -0,0 +1,12 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
<h2>Welcome to Apache Tiles integration with Spring MVC</h2>
</body>
</html>

View File

@@ -0,0 +1,12 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring MVC</title>
</head>
<body>
<h2>Spring MVC configured to work with Apache Tiles</h2>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title><tiles:getAsString name="title" /></title>
<link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link>
</head>
<body>
<div class="flex-container">
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="menu" />
<article class="article">
<tiles:insertAttribute name="body" />
</article>
<tiles:insertAttribute name="footer" />
</div>
</body>
</html>

View File

@@ -0,0 +1,2 @@
<footer>copyright <20> Baeldung</footer>

View File

@@ -0,0 +1,3 @@
<header>
<h1>Welcome to Spring MVC integration with Apache Tiles</h1>
</header>

View File

@@ -0,0 +1,8 @@
<nav class="nav">
<a href="${pageContext.request.contextPath}/"></a>
<ul id="menu">
<li><a href="${pageContext.request.contextPath}/">Home</a></li>
<li><a href="${pageContext.request.contextPath}/springmvc">SpringMVC</a></li>
<li><a href="${pageContext.request.contextPath}/apachetiles">ApacheTiles</a></li>
</ul>
</nav>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<!-- Template Definition -->
<definition name="template-def"
template="/WEB-INF/views/tiles/layouts/defaultLayout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/views/tiles/templates/defaultHeader.jsp" />
<put-attribute name="menu" value="/WEB-INF/views/tiles/templates/defaultMenu.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/views/tiles/templates/defaultFooter.jsp" />
</definition>
<!-- Main Page -->
<definition name="home" extends="template-def">
<put-attribute name="title" value="Welcome" />
<put-attribute name="body" value="/WEB-INF/views/pages/home.jsp" />
</definition>
<!-- Apache Tiles Page -->
<definition name="apachetiles" extends="template-def">
<put-attribute name="title" value="ApacheTiles" />
<put-attribute name="body" value="/WEB-INF/views/pages/apachetiles.jsp" />
</definition>
<!-- Spring MVC Page -->
<definition name="springmvc" extends="template-def">
<put-attribute name="title" value="SpringMVC" />
<put-attribute name="body" value="/WEB-INF/views/pages/springmvc.jsp" />
</definition>
</tiles-definitions>

View File

@@ -0,0 +1,36 @@
.flex-container {
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
text-align: center;
}
.flex-container > * {
padding: 15px;
-webkit-flex: 1 100%;
flex: 1 100%;
}
.article {
text-align: left;
}
header {background: black;color:white;}
footer {background: #aaa;color:white;}
.nav {background:#eee;}
.nav ul {
list-style-type: none;
padding: 0;
}
.nav ul a {
text-decoration: none;
}
@media all and (min-width: 768px) {
.nav {text-align:left;-webkit-flex: 1 auto;flex:1 auto;-webkit-order:1;order:1;}
.article {-webkit-flex:5 0px;flex:5 0px;-webkit-order:2;order:2;}
footer {-webkit-order:3;order:3;}
}