Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

Spring MVC 3.0学习笔记

21
Aug
2012

Spring MVC 3.0学习笔记

By Alex
/ in Java
/ tags MVC, 学习笔记
0 Comments
Spring MVC框架简介
Spring MVC 3.0新特性
  1. 支持REST风格的URL
  2. 添加更多注解,可完全注解驱动
  3. 引入HTTP输入输出转换器(HttpMessageConverter)
  4. 和数据转换、格式化、验证框架无缝集成
  5. 对静态资源处理提供特殊支持 更加灵活的控制器方法签名,可完全独立于Servlet API
Spring MVC的请求处理框架

请求处理过程的细节分析:MVC模式

下图说明了Spring MVC的请求处理流程:

springmvc-process-flow

结合例子:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kingsmartsi.bmcs.sysmgr.ctrl;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
//Indicate that UserController is a Handler
@RequestMapping ( "/user" )
public class UserController
{
    @RequestMapping ( value = "/home" )
    //Request path to serve, relative to /user
    public String register()
    {
        return "sysmgr/user"; //Logic view name
    }
}

则处理流程图为: springmvc-process-flow-ex

请求地址映射
Spring MVC进行映射的依据

Spring MVC是根据来自HTTP请求报文中的各项属性来判断由哪一个Handler来处理当前请求的:
http

URL通配符和路径变量

@RequestMapping不但支持标准的URL,还支持在URL中包含Ant风格的通配符:

1
2
3
4
5
6
*匹配0-N个字符
/user/*/create-user      匹配 /user/any/create-user
**匹配0-N个目录
/user/**/create-user     匹配 /user/create-user、/user/any/create-user
?匹配单个字符
/user/create-user ??     匹配 /user/create-user00

@RequestMapping的URL中可以包含路径变量:

1
/user/{id}   匹配 /user/10000

一个URL中可以包含多个路径变量。 

绑定路径变量(@PathVariable注解)

使用此注解可以把路径变量绑定为处理请求的方法的参数。 启用-debug编译时,如果路径变量名和方法参数名一致,可以自动匹配:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/sysmgr/user/{id}")
public ModelAndView get(@PathVariable("id") String id){
    ModelAndView mv = new ModelAndView();
    mv.setViewName("user/user-detail");
    mv.addObject("user", userService.getUserById(id));
    return mv;
}
 
@RequestMapping("/sysmgr/user-role/{userId}")
public ModelAndView getRole(@PathVariable String userId){
    ModelAndView mv = new ModelAndView();
    mv.setViewName("user/user-role");
    mv.addObject("user", userService.getRoles(id));
    return mv;
}
限定HTTP方法的映射

HTTP方法,在HTTP协议中称为动词(verb),除了常用的(GET和POST)之外,标准方法集合中还包含PUT、DELETE、HEAD和OPTIONS。一般浏览器只支持GET和POST方法。各方法说明如下:

序号

请求方法

说明

1

GET

使用GET方法检索一个表述(representation)——也就是对资源的描述。多次执行同一GET请求,不会对系统造成影响,GET方法具有幂等性[指多个相同请求返回相同的结果]。GET请求可以充分使用客户端的缓存。

2

POST

POST方法,通常表示“创建一个新资源”,但它既不安全也不具有幂等性(多次操作会产生多个新资源)。

3

DELETE

DELETE,表示删除一个资源,你也可以一遍又一遍地操作它,直到得出结果:删除不存在的东西没有任何问题

4

PUT

幂等性同样适用于PUT(基本的含义是“更新资源数据,如果资源不存在的话,则根据此URI创建一个新的资源”)

示例
Java
1
2
3
4
5
6
7
8
9
10
11
//处理任何HTTP方法:
@RequestMapping(value="/delete")
public String del(@RequestParam("userId") String userId){
    return "user/del";            
}
 
//仅处理POST方法提交的请求:
@RequestMapping(value="/delete",method=RequestMethod.POST)
public String del(@RequestParam("userId") String userId){
    return "user/del";            
}

Spring还提供了模拟HTTP方法的机制:通过在web.xml中配置一个org.springframework.web.filter.HiddenHttpMethodFilter,利用POST请求的_method参数指定HTTP方法,HiddenHttpMethodFilter动态更改HTTP头信息。

限定请求参数/请求头的映射

请求参数限定支持如下格式。这些格式同样适用于请求头限定:

  1. param1 :表示请求必须包含名为param1的请求参数
  2. !param1 :表示请求不能包含名为param1的请求参数
  3. param1!=value1 :表示请求包含名为param1的请求参数,但其值不能为value1
  4. {"param1=value1","param2"} :请求必须包含名为param1和param2的两个请求参数,且param1参数的值必须为value1
示例
Java
1
2
3
4
5
6
7
8
9
10
11
//通过请求参数限定
@RequestMapping(value="/delete", params="userId")
public String test1(@RequestParam("userId") String userId){
    ...            
}
 
//通过请求头限定
@RequestMapping(value="/show",headers="content-type=text/*")
public String test2(@RequestParam("userId") String userId){
     ...            
}
请求数据的绑定

Spring MVC总是把各种请求数据绑定到Handler的入参中,其行为主要取决于注解配置。

绑定不同来源的数据

常用数据绑定注解包括:

 注解 说明 
@RequestParam 绑定请求参数(包括URL参数)
@RequestHeader 绑定请求头
@CookieValue 绑定Cookie值
@PathVariable 绑定路径变量,已经在上一章介绍
举例
Java
1
2
3
4
5
6
7
@RequestMapping(value="/handle")
public String handle(@CookieValue("JSESSIONID") String sessionId,
       @RequestHeader("Accept-Language") String accpetLanguage){
}
@RequestMapping(value="/handle")
public String handle(@RequestBody User u){
}
@RequestParam

@RequestParam注解用于绑定单个GET/POST请求参数到Handler的入参,它以下三个参数:

参数  说明 
value 请求参数的名称
required 是否必需,默认为true,表示请求中必须包含对应的参数名,如果不存在将抛出异常
defaultValue 默认参数名,设置该参数时,自动将required设为false

如果Handler入参类型是:

  1. Map,且注解指定了请求参数的名称,那么该参数的值依据配置的转换服务,转换为Map对象
  2. Map<String, String>或者MultiValueMap<String, String>,且注解没有指定请求参数的名称,那么所有请求参数被注入到入参中
举例
Java
1
public String request(@RequestParam("username") String username) {} 
绑定请求参数为对象

Spring MVC支持绑定请求参数到POJO。按:HTTP请求参数名 = POJO的属性名的规则,自动绑定请求数据,支持级联属性名(属性导航),自动进行基本类型数据转换。使用级联属性名时,会自动创建点号导航牵涉到的对象,甚至是集合对象:

Java
1
2
3
4
5
6
7
8
9
10
11
@RequestMapping(value = "/save")
public String save( User user ) {
    //Request URL : /user/save?address.zip=1
    assertEquals(1,user.getAddress().getZip());
}
@RequestMapping ( value = "/save" )
public void save( User user )
{
    //Request URL : /user/save?addresses[0].zip=1
    assertEquals(1,user.getAddresses().get( 0 ).getZip() );
}

注意:被绑定的Handler入参上不需要注解,Spring MVC会自动从请求参数中查找匹配入参属性的条目。

绑定为命令对象

你还可以把绑定的对象添加到模型中,供视图访问:

Java
1
public String request(@ModelAttribute("u") UserModel user){}

在JSP视图页面中,我们可以通过表达式 ${u.username} 访问到上面绑定的对象。

注入各种对象
对象类型 说明 
Servlet API 可以注入各种Servlet API对象作为Handler的参数,包括HttpServletRequest、HttpServletResponse、HttpSession等
如果Handler自行使用HttpServletResponse返回响应,则Handler的返回值设置成void即可
Spring的Servlet API代理类 Spring MVC在org.springframework.web.context.request包中定义了若干个可代理Servlet原生API类的接口,如WebRequest、NativeWebRequest,它们也允许作为Handler的参数,通过这些代理类可访问请求对象的任何信息
I/O类 Spring MVC允许控制器的Handler使用java.io.InputStream/java.io.Reader及java.io.OutputStream/java.io.Writer作为方法的参数
Spring MVC将获取ServletRequest的InputStream/Reader或ServletResponse的OutputStream/Writer,然后按类型匹配的方式,传递给控制器的Handler入参
其它 除可以注入前述类型的参数以外,还支持java.util.Locale、java.security.Principal,可以通过Servlet的HttpServletRequest 的getLocale()及getUserPrincipal()得到相应的值。如果Handler的入参类型为Locale或Principal,Spring MVC自动从请求对象中获取相应的对象并传递给Handler
HTTP消息转换器机制

消息转换机制是Spring MVC数据绑定机制的补充,是@RequestBody、@ResponseBody注解正常工作的基础,其工作示意图如下:

httpconv

HTTP消息转换器类
Java
1
2
3
4
5
6
7
public interface HttpMessageConverter<T> {
  //从HTTP输入消息中读取一个指定类型的对象
  T read(Class<? extends T> clazz, HttpInputMessage inputMessage);
  //将指定类型的对象写入到HTTP输出消息中
  void write(T t, MediaType contentType, HttpOutputMessage    
    outputMessage);
}

现有的实现类包括:StringHttpMessageConverter、FormHttpMessageConverter XmlAwareFormHttpMessageConverter、ResourceHttpMessageConverter、BufferedImageHttpMessageConverter、ByteArrayHttpMessageConverter SourceHttpMessageConverter、MarshallingHttpMessageConverter Jaxb2RootElementHttpMessageConverter、MappingJacksonHttpMessageConverter RssChannelHttpMessageConverter、AtomFeedHttpMessageConverter。可以支持XML、JSON等常用格式。

@RequestBody和@ResponseBody注解

这两个注解可以将HttpServletRequest的getInputStream()内容绑定到参数,或者将Handler返回值写入到HttpServletResponse的getOutputStream()中。它们支持把请求体绑定为POJO,或者把POJO写入到响应体中。读写的格式由Http消息转换器决定。Http消息转换器不必须手工配置,SpringMVC会根据请求头、请求体等进行灵活的判断。这两个注解的缺点是不能访问请求头、响应头。下面是一个例子:

Java
1
2
3
4
5
6
7
8
@RequestMapping(value = "/handle")
public String handle (@RequestBody  User user) {
}
@ResponseBody
public byte[] handle () throws IOException {
    User user = new User()
    return user;
}
HttpEntity和ResponseEntity类

这两个类和@RequestBody、@ResponseBody类似,可以访问请求头、响应头,但是失去方法签名灵活性优势。下面是一个例子:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping(value = "/handle")
public String handle (HttpEntity<User> httpEntity){  
    User user = httpEntity.getBody();                          
}
@RequestMapping(value = "/handle")  
public ResponseEntity<User> handle(){  
    HttpHeaders headers = new HttpHeaders();  
    MediaType mt=new MediaType("text","json", "UTF-8");  
    headers.setContentType(mt);  
    ResponseEntity<User> re=null;  
    User user = new User("WangZhen");  
    re=new ResponseEntity<User>(user ,headers, HttpStatus.OK);  
    return re;  
}
手工配置消息转换器

httpconv-config

数据转换、格式化、校验
工作原理示意图

databinding-flow

数据类型转换

旧版本的Spring只支持标准的PropertyEditor类型体系,存在以下缺陷:

  1. 只能用于字符串和Java对象的转换,不适用于任意两个Java类型之间的转换
  2. 对源对象及目标对象所在的上下文信息(如注解、所在宿主类的结构等)不敏感,在类型转换时不能利用这些上下文信息实施高级转换逻辑

Spring 3.0在核心模型中添加了一个通用的类型转换模块, ConversionService是Spring类型转换体系的核心接口。Spring 3.0同时支持PropertyEditor和ConversionService 进行类型转换,在Bean配置、Spring MVC的Handler参数绑定中使用类型转换体系进行转换。

由于ConversionService在进行类型转换时,可以使用到Bean类的上下文信息(包括类结构,注解信息),所以可以实施更加高级的类型转换,如注解驱动的格式化等功能:

Java
1
2
3
4
public class User {
      @DateTimeFormat(pattern="yyyy-MM-dd")
      private Date birthday;
}

以上User类,通过一个@DateTimeFormat注解,为类型转换提供了一些“额外”的信息,即代表日期的“源字符器”格式是“yyyy-MM-dd”。

自定义类型转换器
实现类型转换器

你可以实现org.springframework.core.convert.converter.Converter<From,To>以自定义转换器:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
public class DateTimeConvertor implements Converter<String, Date> {
 
    private String[] formats;
 
    public DateTimeConvertor( String[] formats ) {
        this.formats = formats;
    }
 
    public Date convert( String source ) {
        return DateUtils.parseDate( source, formats );
    }
 
}
注册到Spring

编写类型转换器完毕后,必须在Spring上下文中注册,才能生效:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 此工厂生成的对象是org.springframework.format.support.FormattingConversionService,它同时是转换服务、格式化服务-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!-- 它持有一系列的转换器 -->
    <property name="converters">
        <set>
            <bean class="com.kingsmartsi.ssheutils.spring.DateTimeConvertor">
                <constructor-arg>
                    <array>
                        <value>#{appCfg.dateFormat}</value>
                        <value>#{appCfg.dateTimeFormat}</value>
                    </array>
                </constructor-arg>
            </bean>
        </set>
    </property>
</bean>
数据格式化机制

上面的FormattingConversionService除了可以持有一系列的转换器(converters),还可以持有一系列的格式化器(formatters)。格式化器用来将来自HTTP请求报文的文本转换为Java数据类型,或者反向转换: data-formatter

自定义格式化器

你可以实现org.springframework.format.Formatter<T>接口,以便把HTTP文本解析为T类型对象,以及把T类型对象格式化为HTTP文本:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DateTimeFormatter implements Formatter<Date> {
 
    private String[] formats;
 
    public DateTimeFormatter( String[] formats ) {
        this.formats = formats;
    }
 
    // 此方法用于将HTTP文本解析为Java对象
    @Override
    public Date parse( String text, Locale locale ) throws ParseException {
        return null;
    }
    // 此方法用于将Java对象转换为HTTP文本
    @Override
    public String print( Date object, Locale locale ) {
        return null;
    }
}
注册到Spring

自定义的格式化器需要到Spring上下文注册:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="formatters">
        <set>
            <bean class="com.kingsmartsi.ssheutils.spring.DateTimeFormatter">
                <constructor-arg>
                    <array>
                        <value>#{appCfg.dateFormat}</value>
                        <value>#{appCfg.dateTimeFormat}</value>
                    </array>
                </constructor-arg>
            </bean>
        </set>
    </property>
</bean>

Spring默认的 <mvc:annotation-driven/> 标签默认创建的ConversionService实例就是一个FormattingConversionServiceFactoryBean,自动支持如下的格式化注解:

格式化注解  说明 
@NumberFormatter 用于数字类型对象的格式化
@CurrencyFormatter 用于货币类型对象的格式化
@PercentFormatter 用于百分数数字类型对象的格式化
Spring对JSR-303的支持

JSR-303是Java为Bean数据合法性校验所提供的标准框架,它已经包含在Java EE 6.0中。JSR-303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。JSR-303包含的注解有:

注解  功能说明
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期

Spring 3.0拥有自己独立的数据校验框架,位于Spring的org.springframework.validation包。该框架同时支持JSR- 303标准的校验框架。Spring 的DataBinder在进行数据绑定时,可同时调用校验框架完成数据校验工作。在Spring MVC中,则可直接通过注解驱动的方式进行数据校验。
需要注意的是,Spring本身没有提供JSR-303的实现,所以必须将JSR- 303的实现者(如Hibernate Validator)的jar文件放到类路径下,Spring将自动加载并装配好JSR-303的实现者。

数据验证注解示例

  <mvc:annotation-driven/> 会默认装配好一个LocalValidatorFactoryBean,通过在Handler参数上标注@Valid注解即可让Spring MVC在完成数据绑定后执行数据校验的工作。
在已经标注了JSR-303注解的、作为Handler参数的POJO前标注一个@Valid,Spring MVC框架在将请求数据绑定到该对象后,就会调用校验框架根据注解声明的校验规则实施校验:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class User {  
    @Pattern(regexp="w{4,30}")
    private String userName;
    @Length(min=2,max=100)
    private String realName;
    @Past
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birthday;
    @DecimalMin(value="1000.00")
    @DecimalMax(value="100000.00")
    @NumberFormat(pattern="#,###.##")
    private long salary;
}
@Controller
public class UserController{
    @RequestMapping
    public String handle(
        //可以在被验证对象后面紧跟着参数用于存放验证结果,这些参数必须是BindingResult或Errors类型
        @Valid User user, BindingResult br, //User和其绑定结果的对象
        @Valid Dept dept, Errors errors   //Dept和其校验的结果对象
){}
数据模型控制
数据模型访问示意图

access-data-model

访问数据模型

可以通过ModelAndView访问:

Java
1
2
3
4
5
6
7
8
@RequestMapping(method = RequestMethod.POST)
public ModelAndView createUser(User user) {
    userService.createUser(user);
    ModelAndView mv = new ModelAndView();
    mv.setViewName("user/createSuccess");
    mv.addObject("user", user);
    return mv;
}

也可以通过@ModelAttribute访问:

Java
1
2
3
4
5
6
7
8
9
10
11
12
//Handler会先执行该方法,获取一个初始的User对象,并使用请求覆盖对应属性
@ModelAttribute("user")
public User getUser(){
    User user = new User();
    user.setUserId("1001");
    return user;
}
@RequestMapping(value = "/handle")
public String handle(@ModelAttribute("user") User user){
    user.setUserName("tom");
    return "/user/showUser";
}

如果Handler方法的参数中有:org.springframework.ui.Model、java.util.Map类型,SpringMVC会自动把请求中隐含的模型对象传递给这些参数:

Java
1
2
3
4
5
6
7
@RequestMapping(value = "/handle")
public String  handle (ModelMap modelMap){
     modelMap.addAttribute("test",“val");
     User user = (User)modelMap.get("user");
     user.setUserName("wz");        
     return "/user/showUser";
}

如果希望在多个请求之间共用某个模型属性数据,则可以在控制器类标注一个@SessionAttributes,Spring MVC会将模型中对应的属性暂存到HttpSession中:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Controller
@RequestMapping("/user")
@SessionAttributes("user")//声明会话属性
public class UserController {
    @RequestMapping(value = "/handle0")
    public String  handle0(@ModelAttribute("user") User user){//设置会话属性
        user.setUserName("John");
        return "redirect:/user/handle1.html";
    }
    @RequestMapping(value = "/handle1")
    public String  handle1(ModelMap modelMap,SessionStatus sessionStatus){
        User user = (User)modelMap.get("user");//获取会话属性
        if(user != null){
            user.setUserName("Jetty");
            sessionStatus.setComplete();//清除会话属性    
        }
        return "/user/showUser";
    }        
}
视图及解析器
视图解析原理

view-resolver

视图解析器的分类
  1. 完成单一解析逻辑的视图解析器:InternalResourceViewResolver、FreeMarkerViewResolver、BeanNameViewResolver、XmlViewResolver等
  2. 协商视图解析器:ContentNegotiatingViewResolver。该解析器是Spring 3.0新增的,它不负责具体的视图解析,而是作为一个中间人的角色根据请求所要求的MIME类型(Accept请求头),从上下文中选择一个适合的视图解析器,再将视图解析工作委托其负责
视图解析器的配置

视图解析器Bean的parameterName可以用来判断请求所期望的MIME类型,order则声明视图解析器的优先级:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
    p:order="0" p:defaultContentType="text/html" p:ignoreAcceptHeader="true"
    p:favorPathExtension="false" p:favorParameter="true" p:parameterName="content">
    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
      <entry key="xml" value="application/xml" />  
            <entry key="json" value="application/json" />
        </map>
    </property>
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"
                p:renderedAttributes="userList" />
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView"
                p:modelKey="userList" p:marshaller-ref="xmlMarshaller" />
        </list>
    </property>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:order="100" p:viewClass="org.springframework.web.servlet.view.JstlView"
    p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
静态资源处理
静态资源的配置

在web.xml让所有请求都由Spring MVC处理,注意url-pattern是/而不是/*:

Java
1
2
3
4
5
6
7
8
9
10
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

在MVC的Spring配置文件中设置:

spring-mvc.xml
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 设置默认,大多数应用服务器的Servlet的名称都是“default” -->
<mvc:default-servlet-handler default-servlet-name="default"/>
<!-- 物理静态资源路径映射逻辑资源路径 -->
<mvc:resources mapping="/resources/**" location="/,classpath:/META-INF/publicResources/"/>
<mvc:resources mapping="/json/**" location="/json/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/icons/**" location="/icons/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/themes/**" location="/themes/" />
<mvc:resources mapping="/sound/**" location="/sound/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/html/**" location="/html/" /> 
← Ubuntu下安装MySQL
控制组详解 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • SpringMVC知识集锦
  • ExtJS 4的MVC框架
  • MVC模式
  • Log4J2学习笔记
  • Bazel学习笔记

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2