Brief introduction
Previous page program service code is embedded into the JSP page, higher coupling.
Later, after the separation of the front and rear ends of the code, using the MVC architecture, M: a view showing, in charge of view, C:: Model, the data model is responsible for the control, V controller, responsible for the data model is rendered onto the respective views.
Request Process
┌─────────┐
↗│ 处理器映射│
2/ └─────────┘
/ 3
请求 1 ┌─────────────────┐ --------------------> ┌─────┐
----->│DispatcherServlet│ <--┌─────────────┐ 4 │控制器│
└─────────────────┘ │模型及逻辑视图名│ ---│ │
\ \ └─────────────┘ └─────┘
\ \5 ┌────────┐
6\ --->│视图解析器│
↘ └────────┘
响应 7 ┌────┐
<----------------------│视图 │
└────┘
process:
- Request: When asked to leave the browser, the user can with the information requested by the content, at least contain the URL request. (And possibly also with information such as forms)
- DispatcherServlet: Spring MVC sends the request to the controller (Controller)
DispatcherServlet
: Unlike most Java-based Web frameworks, all requests will be via a Spring MVC front controller (front controller) Servlet. In this embodiment of a single Servlet delegates the request to other components of the application to perform the actual process. In Spring MVC in, DispatcherServlet is the front controller.DispatcherServlet
The task is to send the request to the controller Spring MVC (controller
). (Spring controller is a component for processing the request.)DispatcherServlet
You need to know which sends the request to the controller. SoDispatcherServlet
with one or more queries处理器映射(handler mapping
where) to determine the next stop on request. The mapping processor to make decisions based on the URL information request carried.- To the controller, the load request will remove (User Submission) and wait controller processes the information. (In fact, well-designed controller itself only deals with little or no processing, but the business logic entrusted to one or more service objects are processed)
- After completion logic controller, typically have some information that needs to be returned to the user and displayed on the browser. This information is referred to as model
model
( ).- This information is usually need to be formatted in a user-friendly manner, it will generally be HTML. Therefore, the information needs to be sent to a view (
view
), usually a JSP.
- The controller did last thing is to model data package and identify the name of the view for rendering output. Then it will request along
模型
and视图名
sent backDispatcherServlet
.- Passed to
DispatcherServlet
the view name does not directly indicate a specific JSP. In fact it can not even determine the view is JSP. Instead, it just passed a逻辑名称
, this name will be used to find the real view to produce results.DispatcherServlet
It will be used视图解析器(view resolver)
to match the logical view name for a specific view implementations, it may or may not JSP.- Using a model view will render output data, the output will be passed to the client in response to the object.
Configuration DispatcherServlet
DispatcherServlet
You can configure the web.xml
file.
AbstractAnnotationConfigDispatcherServletInitializer
In the specification and Spring 3.1 Servlet 3, the java can be DispatcherServlet
arranged in Servlet容器
the required inheritance AbstractAnnotationConfigDispatcherServletInitializer
, override three methods.
package com.yww.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ RootConifg.class };
}
@Override
protected Class<?>[] getServletConfigClasses() { // 指定配置类
return new Class[]{ WebConfig.class };
}
@Override
protected String[] getServletMappings() { // 将DispatcherServlet映射到"/"
return new String[]{ "/" };
}
}
getServletMappings()
: Will be mapped to one or more pathsDispatcherServlet
on. In this example, it maps is "/
", which means it will be the default Servlet application. It handles all requests into the application.- To understand the other two methods, we must first understand
DispatcherServlet
andServlet监听器(ContextLoaderListener)
relationships. (as follows)
AbstractAnnotationConfigDispatcherServletInitializer
| |
创建 创建
| |
v v
DispatcherServlet ContextLoaderListener
| |
加载 加载
| |
v V
应用上下文 应用上下文
(查找@Configuration注解的类, (查找@Configuration注解的类,
加载包含Web组件的bean。 加载应用中的其它bean。
如控制器,视图解析器,处理器映射等) 如自定义的业务所需的bean)
AbstractAnnotationConfigDispatcherServletInitializer
Analysis :
- The container looks implemented in the class path in Servlet 3.0 environment
javax.servlet.ServletContainerInitializer
class interface, if they can find, they would use it to configure the Servlet container.- Spring provides an implementation of this interface, called
SpringServletContainerInitializer
, in turn, will find this class to achieveWebApplicationInitializer
class and give them tasks to complete the configuration.- Spring 3.2 introduces a convenient
WebApplicationInitializer
base to achieve, that isAbstractAnnotationConfigDispatcherServletInitializer
.- When our custom class inherits
AbstractAnnotationConfigDispatcherServletInitializer
when deployed toServlet 3.0容器
time in the container it will automatically find it, and to configureServlet上下文
.
容器(Servlet 3.0)
|类路径查找
v
实现javax.servlet.ServletContainerInitializer接口的类
|
v
SpringServletContainerInitializer(Spring提供)
|查找
v
实现`WebApplicationInitializer`的类,将配置的任务交给它们完成
|
AbstractDispatcherServletInitializer
AbstractContextLoaderInitializer
|
v
AbstractAnnotationConfigDispatcherServletInitializer(Spring提供)
|
v
自定义类继承,即可配置Servlet上下文
Servlet configuration class
Role: Enable Web MVC, enable the component scanning, configuration view resolver configuration process static resources.
WebConfig.java
In the above getServletConfigClasses()
setting process.
The simplest configuration :
package com.yww.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@EnableWebMvc
public class WebConfig {
}
Empty configuration WebConfig
although can enable Spring MVC, but there are many problems:
- No configuration view resolver. Spring will default
BeanNameVire-Resolver
, this view resolver will find the view ID matches the name of the bean, bean and look to achieve View interface, which parses the view in such a way. - Not enabled component scans. Spring can only be found explicitly declared in the configuration controller class.
DispatcherServlet
It will be mapped to the default Servlet application, so it will process all requests, including requests for static resources.
But the smallest available Spring MVC configuration :
package com.yww.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.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc // 启用Spring MVC
@ComponentScan // 启用组件扫描
public class WebConfig extends WebMvcConfigurationSupport {
// 配置JSP视图解析器
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
// 配置静态资源的处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
@ComponentScan
You will find with @Controller
class notes, so we do not need to explicitly declare the class in the configuration controller.
ViewResolver
Looks for JSP files as prefix and suffix set.
configureDefaultServletHandling()
The method by calling DefaultServletHandlerConfigurer
the enable()
method requires DispatcherServlet
will forward the request to the static resources Servlet容器
on the default Servlet, rather than DispatcherServlet
their own to deal with such requests.
Root configuration class
Role: Load custom business component.
package com.yww.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 = {"com.yww"},
excludeFilters = {@Filter(type= FilterType.ANNOTATION, value = EnableWebMvc.class)}
)
public class RootConfig {
}
Controller
Controller Notes :
@Controller
Is based on the @Component
notes, the effect is the same. But in the MVC @Component
in the ideographic it could be worse.
Mapping annotations :
@RequestMapping
It specifies the path to process the request.
It can be placed on the type, or method. Setting map on the path to the group, which in this embodiment further requires specifying the requested annotation.
Or a method of mapping the same class can have multiple paths.
Return value - View name :
The returned string will be interpreted as Spring MVC view name to render. DispatcherServlet
View resolvers will be asked to resolve the logical name for the actual view.
InternalResourceViewResolver
Recognizes returned with a prefix character redirect:
or forward:
, respectively, they are redirected to go.
Model parameters :
Data transfer parameters of the model are three kinds: Model
, ModelMap
, ModelAndView
.
Their relationship is as follows.
public class ExtendedModelMap extends ModelMap implements Model{}
ModelAndView
Compared to other purposes, you can set the rendering of the view name.
Model calls addAttribute()
method does not specify when the key, key will be determined according to the type inference object.
It may be Map
the type to model.
Or even can return a list, or when the processor returns a collection of objects, this value will be placed in the model, key will come to the model according to its type inference. And the noun logical view will be inferred according to the request path.
When the view is a JSP, the model data will be placed in the request as a request attribute.
model
Check the properties can be achieved annotate the model. Also pass parameters in the controller before adding @Valid
annotations, and the 紧接着
additional parameters Errors
acquired abnormalities.
Java校验注解:@AssertFalse, @AssertTrue, @DecimalMax, @DecimalMin, @Digits, @Future, @Max, @Min, @NotNull, @Null, @Past, @Pattern, @Size。
Examples
- Basic MVC program
- Accept the request input
-
- Path parameters
-
- Form parameters
Basic MVC program
xml configuration DispatcherServlet
Project structure
.
├── build.gradle
└── src
└── main
├── java
│ └── com
│ └── yww
│ ├── HomeController.java
│ └── Message.java
├── resources
│ └── application.properties
└── webapp
├── index.jsp
└── WEB-INF
├── applicationContext.xml
├── dispatcher-servlet.xml
├── jsp
│ └── home.jsp
└── web.xml
Code
build.gradle
plugins {
id 'java'
id 'war'
}
group = 'com.yww'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext{
springVersion = '5.2.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-context:$springVersion"
compile "org.springframework:spring-beans:$springVersion"
compile "org.springframework:spring-expression:$springVersion"
compile "org.springframework:spring-aop:$springVersion"
compile "org.springframework:spring-aspects:$springVersion"
compile "org.springframework:spring-web:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
testCompile "junit:junit:4.12"
}
web.xml
: Configuring DispatcherServlet
and map the path, ContextLoaderListener
(load any bean named xml file), bean xml configuration file.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<!-- <url-pattern>*.form</url-pattern>-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
dispatcher-servlet.xml
: Xxx-servlet.xml designated format file is automatically loaded spring mvc, configured path view resolved.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.yww"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
applicationContext.xml
: Configure the ContextLoaderListener
post, you can load xml file naming any of the bean without xxx-servlet.xml format.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="msg1" class="com.yww.Message">
<property name="msg" value="mvc - xml config"/>
</bean>
</beans>
HomeController.java
package com.yww;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.beans.factory.annotation.Autowired;
@Controller
@RequestMapping("/home")
public class HomeController {
@Autowired
public Message msg1;
@RequestMapping(method = RequestMethod.GET)
public String printHome(Model model){
String str1 = msg1.getMsg();
model.addAttribute("msg", "this is a page! gradle " + str1);
return "home";
}
}
Message.java
package com.yww;
public class Message {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = "this mssage is : " + msg;
}
}
index.jsp
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
home.jsp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>${msg}<h1>
</body>
</html>
start up
- Project Structe -> Artifacts -> + -> WebApplication:Exploded -> From Modules... -> OK
- Project Structe -> Artifacts -> + -> WebApplication:Archive -> For 'xxx:war exploded' -> OK
- Edit Configurations... -> + -> Tomcat Server -> local -> Deployment -> + Artifact... -> OK
- run(shift + F10)
java configuration DispatcherServlet
Project structure
.
├── build.gradle
└── src
└── main
├── java
│ └── com
│ └── yww
│ ├── config
│ │ ├── MyWebAppInitializer.java
│ │ ├── RootConfig.java
│ │ └── WebConfig.java
│ ├── HomeController.java
│ └── Message.java
├── resources
│ └── application.properties
└── webapp
├── index.jsp
└── WEB-INF
├── jsp
│ └── home.jsp
└── web.xml
Code
build.gradle
: Unlike the previous, java configuration DispatcherServlet, you need to add servlet-api
the library.
plugins {
id 'java'
id 'war'
}
group = 'com.yww'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext{
springVersion = '5.2.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-context:$springVersion"
compile "org.springframework:spring-beans:$springVersion"
compile "org.springframework:spring-expression:$springVersion"
compile "org.springframework:spring-aop:$springVersion"
compile "org.springframework:spring-aspects:$springVersion"
compile "org.springframework:spring-web:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
testCompile "junit:junit:4.12"
providedCompile 'javax.servlet:javax.servlet-api:4.0.1'
}
web.xml
: Nothing to configure, fully configured using java.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
MyWebAppInitializer.java
package com.yww.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() { // 指定配置类
return new Class[]{ WebConfig.class };
}
@Override
protected String[] getServletMappings() { // 将DispatcherServlet映射到"/"
return new String[]{ "/" };
}
}
WebConfig.java
package com.yww.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.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc // 启用Spring MVC
//@ComponentScan("com.yww")
@ComponentScan // 启用组件扫描,只会扫描当前包下的配置
public class WebConfig extends WebMvcConfigurationSupport {
// 配置JSP视图解析器
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
// 配置静态资源的处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
RootConfig.java
package com.yww.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 = {"com.yww"},
excludeFilters = {@Filter(type= FilterType.ANNOTATION, value = EnableWebMvc.class)}
)
public class RootConfig {
}
HomeController.java
(Ibid)
Message.java
(Ibid)
index.jsp
(Ibid)
home.jsp
(Ibid)
Accept the request input
Spring MVC in various ways to allow the client to transfer data to the processor controller method:
- Query parameters (Query Parameter)
- Form parameters (Form Parameter)
- Path variables (Path Variable)
Project structure
.
├── build.gradle
└── src
└── main
├── java
│ └── com
│ └── yww
│ ├── dao
│ │ └── User.java
│ ├── FormParamController.java
│ ├── PathParamController.java
│ └── QueryParamController.java
├── resources
│ └── application.properties
└── webapp
├── index.jsp
└── WEB-INF
├── applicationContext.xml
├── dispatcher-servlet.xml
├── jsp
│ ├── form.jsp
│ └── home.jsp
└── web.xml
Code
User.java
package com.yww.dao;
public class User {
private int id;
private String name;
private String passwd;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
QueryParamController.java
package com.yww;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class QueryParamController {
@RequestMapping(value = "/query_param", method = RequestMethod.GET)
public String printHome(
Model model,
@RequestParam int id,
@RequestParam(value = "name", defaultValue = "yww") String username,
@RequestParam(value = "count", defaultValue = "10") long count // 尽管defaultValue属性给定的时String类型的值,但当绑定到方法的count参数时,会自动转换为long类型。
){
String str1 = " query - id:" + id + " username:" + username + " count:" + count;
model.addAttribute("msg", "this is a page! " + str1);
return "home";
}
}
PathParamController.java
package com.yww;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class PathParamController {
@RequestMapping(value = "/path_param/{id}", method = RequestMethod.GET)
public String printHome(
Model model,
@PathVariable("id") int id
){
String str1 = " path - id:" + id;
model.addAttribute("msg", "this is a page! " + str1);
return "home";
}
}
FormParamController.java
package com.yww;
import com.yww.dao.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import static org.springframework.web.bind.annotation.RequestMethod.*;
@Controller
public class FormParamController {
@RequestMapping(value = "/form_param", method = GET)
public String showForm(){
return "form";
}
@RequestMapping(value = "/form_param", method = POST)
public String postForm(
Model model,
User user
){
model.addAttribute("msg", "this is a page! form : " + user.getName());
return "home";
}
}
form.jsp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
id : <input type="text" name="id" /> </br>
name : <input type="text" name="name" /> </br>
password : <input type="text" name="passwd" /> </br>
<input type="submit" value="login" />
</form>
</body>
</html>
start up
Query parameters (Query Parameter): http: // localhost: 8080 / mvc_param / query_param id = 1001 & name = megumin & count = 7?
Path variables (Path Variable): http: // localhost: 8080 / mvc_param / path_param / 1001
Form parameters (Form Parameter): http: // localhost: 8080 / mvc_param / form_param
PS
Note: xml configuration file
Xxx-servlet.xml designated file format are automatically loaded spring mvc (eg: dispatcher-servlet.xml).
The configuration ContextLoaderListener
, the load xml document on the bean arbitrarily named without xxx-servlet.xml format (eg: applicationContext.xml).
错误:class file for javax.servlet.ServletException not found
java configuration DispatcherServlet
, you need to build.gradle
add the library:
`providedCompile 'javax.servlet:javax.servlet-api:4.0.1'`
Note: The form submission path
<form>
Tag action attribute is not set, then, when the form is submitted, it will be submitted to the same url path and presentation.