1. request的一生
2. 设置Spring MVC
2.1 配置DispatcherServlet
DispatcherServlet是Spring MVC的核心。
在Spring application's servlet context中, 任何继承AbstractAnnotationConfigDispatcherServletInitializer的类都会被自动用来配置DispatcherServlet和Spring application Context。
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}
2.2 两种application context
- 当DispatcherServlet启动时,它会创建一个Spring application context,然后向里面加载指定的bean,主要是 controllers, view resolvers, and handler mappings
- 在Spring web应用中,ContextLoaderListener会创建另外一个application context,用来加载其他bean
配置AbstractAnnotationConfigDispatcherServletInitializer是为了替代web.xml配置
环境要求:Tomcat 7 及以上 需要支持Servlet3.0
2.3 开启Spring MVC
- 使用xml配置
<mvc:annotation-driven>
- 使用@EnableWebMvc注解
package spittr.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@EnableWebMvc
public class WebConfig {
}
注意:
(1) 这里没有配置view resolver,Spring会默认使用BeanNameViewResolver,寻找ID匹配并且实现了View接口的Bean
(2) DispatcherServlet会作为默认的servlet,并处理所有的请求
package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("spitter.web") //开启自动扫描
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* 配置视图解析器
*/
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
/**
* 配置静态内容处理器
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
configurer.enable();
}
}
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages={"spitter"},
excludeFilters={@Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)
})
public class RootConfig {
}
3. Controller
@Controller
public class HomeController {
@RequestMapping(value="/", method=GET)
public String home() {
return "home";
}
}
@Controller注解表明当前bean是一个controller
@RequestMapping表明当前类所处理的request路径,可以在类上注解,也可以在方法上注解,在类上注解表明当前controller所要处理的请求的根路径
@Controller
@RequestMapping("/")
public class HomeController {
@RequestMapping(method=GET)
public String home() {
return "home";
}
}
@Controller
@RequestMapping({"/", "/homepage"})
public class HomeController {
}
向view传递数据
4. 接收请求参数
4.1 @RequestParam
@RequestMapping(value="/show", method=RequestMethod.GET)
public String showSpittle(@RequestParam("spittle_id") long spittleId, Model model) {
model.addAttribute(spittleRepository.findOne(spittleId));
return "spittle";
}
4.2 @PathVariable
@RequestMapping(value="/{spittleId}", method=RequestMethod.GET)
public String spittle(@PathVariable("spittleId") long spittleId, Model model) {
model.addAttribute(spittleRepository.findOne(spittleId));
return "spittle";
}
4.3 使用对象接收参数
@RequestMapping(value="/register", method=POST)
public String processRegistration(Spitter spitter) {
spitterRepository.save(spitter);
return "redirect:/spitter/" +
spitter.getUsername();
}
1. 验证对象参数
使用 Java Validation API
public class Spitter {
private Long id;
@NotNull
@Size(min=5, max=16)
private String username;
@NotNull
@Size(min=5, max=25)
private String password;
@NotNull
@Size(min=2, max=30)
private String firstName;
@NotNull
@Size(min=2, max=30)
private String lastName;
...
}
@RequestMapping(value="/register", method=POST)
public String processRegistration(@Valid Spitter spitter, Errors errors) {
if (errors.hasErrors()) {
return "registerForm";
}
spitterRepository.save(spitter);
return "redirect:/spitter/" + spitter.getUsername();
}
使用@Valid注解表明当前参数需要被验证,验证后的结果放置在Errors对象实例中
5. 渲染web视图
5.1 理解视图解析
将视图渲染从业务逻辑中解耦出来,业务逻辑关心业务逻辑实现,视图解析关注视图渲染
Spring MVC提供了视图解析接口:
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale) throws Exception;
}
View接口:
public interface View {
String getContentType();
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
5.2 渲染JSP
5.2.1 配置internal view resolver
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
或
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp"
/>
解析JSTL视图
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
return resolver;
}
或
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp"
p:viewClass="org.springframework.web.servlet.view.JstlView"
/>
5.3 使用Thymeleaf
5.3.1 配置Thymeleaf视图解析器
/**
* 配置视图解析器
*/
@Bean
public ViewResolver viewResolver( SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
/**
* 配置模板引擎,用于解析模板,并渲染数据
*/
@Bean
public TemplateEngine templateEngine(TemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
/**
* 配置模板解析器,用于定位模板位置
*/
@Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
或
<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver"
p:templateEngine-ref="templateEngine" />
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine"
p:templateResolver-ref="templateResolver" />
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"
p:prefix="/WEB-INF/templates/"
p:suffix=".html"
p:templateMode="HTML5" />
5.3.2 定义Thymeleaf模板
在html中添加Thymeleaf命名空间xmlns:th="http://www.thymeleaf.org":
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spittr</title>
<link rel="stylesheet"
type="text/css"
th:href="@{/resources/style.css}"></link>
</head>
<body>
<h1>Welcome to Spittr</h1>
<a th:href="@{/spittles}">Spittles</a> |
<a th:href="@{/spitter/register}">Register</a>
</body>
</html>
Thymeleaf官方地址:https://www.thymeleaf.org/