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/