Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

41.4. View

41.4.1. 配置静态文件目录

		
#静态资源访问路径
spring.mvc.static-path-pattern=/**

#静态资源映射路径
spring.resources.static-locations=classpath:/		
		
		

41.4.2. 添加静态文件目录

		
package cn.netkiller.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
    }
}		
		
		

41.4.3. Using Spring’s form tag library

41.4.3.1. css

			
	
			
			
cssClass

cssClass 使用该属性指定表单元素CSS样式名,相当于HTML元素的class属性

				
<form:input path="userName" cssClass="inputStyle"/>
				
				
cssStyle

cssStyle 直接通过该属性指定样式,相当于HTML元素的style属性

				
<form:input path="userName" cssStyle="width:100px"/>
				
				
cssErrorClass

cssError Class表示表单元素发生错误时对应的样式

				
<form:input path="userName" cssClass="userNameClass" cssErrorClass= "userNameClassError"/>
				
				

41.4.3.2. cssClass

			
	
			
			

41.4.4. Thymeleaf

http://thymeleaf.org/

41.4.4.1. Maven pom.xml

			
			<dependency>  
	            <groupId>org.springframework.boot</groupId>  
	            <artifactId>spring-boot-starter-thymeleaf</artifactId>  
	        </dependency>  		
			
			

41.4.4.2. Spring 配置

			
	<!-- **************************************************************** -->
	<!-- THYMELEAF-SPECIFIC ARTIFACTS -->
	<!-- TemplateResolver <- TemplateEngine <- ViewResolver -->
	<!-- **************************************************************** -->

	<bean id="templateResolver"
		class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
		<property name="prefix" value="/WEB-INF/templates/" />
		<property name="suffix" value=".html" />
		<property name="templateMode" value="HTML5" />
	</bean>

	<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
		<property name="templateResolver" ref="templateResolver" />
	</bean>

	<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
		<property name="templateEngine" ref="templateEngine" />
	</bean>	
			
			

41.4.4.3. controller

			
package cn.netkiller.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/")
public class HelloController {

	@RequestMapping(value = "/{name}", method = RequestMethod.GET)
	public String getMovie(@PathVariable String name, ModelMap model) {
		model.addAttribute("name", name);
		return "hello";
	}

}			
			
			

41.4.4.4. HTML5 Template

			
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Spring MVC + Thymeleaf Example</title>
</head>
<body>
	Hello, <span th:text="${name}" />!
</body>
</html>
			
			

41.4.4.5. thymeleaf 渲染表格

			
	@RequestMapping("/list")
	public ModelAndView list() {

		Iterable<User> users = userRepository.findAll();

		ModelAndView mv = new ModelAndView();
		mv.addObject("users", users);
		mv.setViewName("table");
		return mv;
	}			
			
			

模板文件

			
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>用户登记</title>
</head>
<body>
	<h1>Welcome to Thymeleaf</h1>
	<table border="1" width="100%">
		<tr>
			<td>ID</td>
			<td>姓名</td>
			<td>联系方式</td>
			<td>详细地址</td>
			<td>图片</td>
		</tr>
		<tr th:each="user : ${users}">
			<td th:text="${user.id}"></td>
			<td th:text="${user.name}"></td>
			<td th:text="${user.tel}"></td>
			<td th:text="${user.address}"></td>
			<td th:text="${user.picture}"></td>
		</tr>
	</table>
</body>
</html>			
			
			

41.4.4.6. URL 链接

			
	<span th:text="${number+1}"></span> /
	<span th:text="${totalPages}"></span>

	<a href="#"
		th:href="@{/api/user/browse?sort=id,desc&size=10(page=${number-1})}">上一页</a>
	<a href="#"
		th:href="@{/api/user/browse?sort=id,desc&size=10(page=${number+1})}">下一页</a>			
			
			

拼接 URL 的方法

			
<img src="#" th:src="${'https://img.netkiller.cn/' + pic}" height="128" th:target="_blank" />			
			
			

41.4.4.7. 拆分字符串

pictures 是一个以逗号分割得字符串。我们需要拆分并逐条显示。

			
	<div th:unless="${picture == null}">
		<a th:each="pic : ${#strings.arraySplit(pictures, ',')}" href="#" th:href="${pic}"> <img src="#" th:src="${pic}" height="64" /></a>
	</div>			
			
			

41.4.4.8. 日期格式化

			
	<span th:text="${#dates.format(createDate, 'yyyy-MM-dd HH:mm')}"></span	
			
			
			

// java.util.Date 处理

${#dates.day(date)}
${#dates.month(date)}
${#dates.monthName(date)}
${#dates.monthNameShort(date)}
${#dates.year(date)}
${#dates.dayOfWeek(date)}
${#dates.dayOfWeekName(date)}
${#dates.dayOfWeekNameShort(date)}
${#dates.hour(date)}
${#dates.minute(date)}
${#dates.second(date)}
${#dates.millisecond(date)}


// java.time 时间处理
${#temporals.day(date)}
${#temporals.month(date)}
${#temporals.monthName(date)}
${#temporals.monthNameShort(date)}
${#temporals.year(date)}
${#temporals.dayOfWeek(date)}
${#temporals.dayOfWeekName(date)}
${#temporals.dayOfWeekNameShort(date)}
${#temporals.hour(date)}
${#temporals.minute(date)}
${#temporals.second(date)}
${#temporals.millisecond(date)}

// 处理天实例

<p th:text="${#dates.day(standardDate)}"></p>
<p th:text="${#temporals.day(localDateTime)}"></p>
<p th:text="${#temporals.day(localDate)}"></p>

// 处理周实例

<p th:text="${#dates.dayOfWeekName(standardDate)}"></p>
<p th:text="${#temporals.dayOfWeekName(localDateTime)}"></p>
<p th:text="${#temporals.dayOfWeekName(localDate)}"></p>

// 处理秒实例

<p th:text="${#dates.second(standardDate)}"></p>
<p th:text="${#temporals.second(localDateTime)}"></p>			
			
			

41.4.5. FreeMarker

http://freemarker.org/

41.4.6. i18n 国际化

41.4.6.1. 在 appliction.properties 中配置启用 i18n

			
spring.messages.basename=message
spring.messages.encoding=UTF-8
			
			

41.4.6.2. 创建语言包文件

创建默认语言包文件 message.properties,当匹配不到语言时使用默认配置

			
member.name=Name
			
			

message_en_US.properties

			
member.name=Name
			
			

message_zh_CN.properties

			
member.name=姓名
			
			

注意:Eclipse 需要安装 properties 编辑工具,否则中文会自动转换成UTF8编码,无法直接阅读。

41.4.6.3. 控制器重引用语言包

RestController

			
@RestController
public class HomeController {
	@Autowired
	private MessageSource messageSource;

	@GetMapping("/lang")
	public String language() {
		String message = messageSource.getMessage("member.name", null, LocaleContextHolder.getLocale());
		return message;
	}
}
			
			

Controller

			
package cn.netkiller.controller;

import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.ui.Model;
import java.util.Locale;

@Controller
public class HomeController {

    @Autowired
    private MessageSource messageSource;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Locale locale, Model model){

        // add parametrized message from controller
        String welcome = messageSource.getMessage("welcome.message", new Object[]{"Neo Chan"}, locale);
        model.addAttribute("message", welcome);
        
        // obtain locale from LocaleContextHolder
        Locale currentLocale = LocaleContextHolder.getLocale();
        model.addAttribute("locale", currentLocale);
        model.addAttribute("startMeeting", "10:30");
        
        return "index";
    }

}			
			
			

41.4.6.4. 参数传递

有时定义语言包会出现一种情况,一个句子中可能存在变量。例如:

恭喜你 XXXX 您已成为我们的会员

这样的需求,如果丁一两个key处理起来会非常麻烦。这里可以定义一个变量,通过参数传递来修改一句话中间的部分。

			
welcome=Welcom to {0}
			
			
			
	@GetMapping("/lang/args")
	public String welcome() {
		String[] args = { "China" };
		String message = messageSource.getMessage("welcome", args, LocaleContextHolder.getLocale());

		return message;
	}
			
			

参数以此类推 {0}, {1} ...... {n}

			
String welcome = messageSource.getMessage("welcome.message", new Object[]{"Neo chen"}, locale);