Spring MVC

1. request的一生

image.png

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

  1. 當DispatcherServlet啟動時,它會創建一個Spring application context,然后向里面加載指定的bean,主要是 controllers, view resolvers, and handler mappings
  2. 在Spring web應用中,ContextLoaderListener會創建另外一個application context,用來加載其他bean

配置AbstractAnnotationConfigDispatcherServletInitializer是為了替代web.xml配置

環境要求:Tomcat 7 及以上 需要支持Servlet3.0

2.3 開啟Spring MVC

  1. 使用xml配置
<mvc:annotation-driven>
  1. 使用@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傳遞數據

image.png

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

image.png

image.png
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;
}
image.png

5.2 渲染JSP

5.2.1 配置internal view resolver
image.png
@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/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容