`
linvar
  • 浏览: 254699 次
  • 性别: Icon_minigender_1
  • 来自: 未定
社区版块
存档分类
最新评论

springmvc 笔记

    博客分类:
  • java
阅读更多

struct2很不好用,springmvc比较给力,跟spring又是无缝链接,所以选择springmvc
用springmvc有一段时间了,记录一下备忘
大多数内容来自spring的官方文档

1.前端分发器DispatcherServlet
springmvc是围绕这个DispatcherSerlet来设计的,
DispatcherSerlet 接受客户端请求,
通过@Controller, @RequestMapping定位一个handler来处理这个请求
处理完成之后调用模板引擎处理handler处理结果数据(model),并返回给客户端
DispatcherSerlet是一个HttpServlet类,在web.xml配置

<servlet>
   <servlet-name>springmvc</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:spring/springmvc-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
   <servlet-name>springmvc</servlet-name>
   <url-pattern>/*</url-pattern>
</servlet-mapping>

2.@Controller
@Controller定义在类上,表明这是一个控制器类,
spring可以在这个控制器里扫描@RequestMapping(定义在控制器的方法里)
所以springmvc的请求处理handler是类中的一个方法
在DispatcherServlet的web.xml
<servlet>定义中有一个参数contextConfigLocation=classpath:spring/springmvc-config.xml
这是springmvc的配置文件,默认在WEB-INF目录下跟servlet-name同名的xml文件
在这个springmvc-config.xml配置文件中,主要有以下配置:

<!-- 定义扫描Controller的base-package -->
<context:component-scan base-package="hello.controller" />
<!-- springmvc的关键配置 -->	
<mvc:annotation-driven />  
<!-- 这个default-servlet-handler 可以使用DispatcherServlet的url-pattern
是/*, 如果springmvc找不到handler来处理请求, 会自动放过,让serlvet container处理 -->  
<mvc:default-servlet-handler/>	
<!-- 这个tag是方便匹配请求跟view, 这个view一般是静态的-->
<mvc:view-controller path="/about" view-name="about" />
<!-- 这个tag是方便重定向路径-->
<mvc:resources mapping="/media/**" location="/media/"/>

[b]3.@RequestMapping[/b]
@RequestMapping定义在@Controller定义过的控制器类的方法上
(也可以定义在类里,这时最终的匹配是类里定义的加上方法定义的mapping)
是一个具体的处理逻辑(handler)
所以这个方法是重点,也是难点, 程序员基本上就是围绕这些@RequestMapping方法来开发
Mapping requests with @RequestMapping
例子说明一切:
(关键词: @RequestMapping, @PathVariable, @RequestParam)

@Controller
public class UserController{
     
    @RequestMapping("/user/login")
    public ModelAndView login(){
      //todo
    }

    @RequestMapping(value="/user/login", method=RequestMethod.GET)
    //...
    
    @RequestMapping("/user/{userId}")
    public ModelAndView(@PathVariable("userId") String userId, ...)
    //....
    
    @RequestMapping("/user/login")
    public ModelAndView(@RequestParam("userId") String userId, ...)
    //....
    
}

//例子中@PathVariable("userId"), @RequestParam("userId")的"userId"可选,
//"if your code is compiled with debugging enabled"
//"/user/login/{user}"中的user不能是中文,应该跟springmvc默认编码有关


4.@RequestMapping 方法的参数类型
@RequestMapping方法的参数是由springmvc框架注入的,你可以定义如下参数类型
1)request, response, session(简写,you know that)
2)java.util.Locale,
3)InputStream, Reader, OutputStream, Writer,
4)java.security.Principal 
5)@PathVariable, @RequestParam, @RequestHeader, @RequestBody
6)HttpEntity<?> parameters for access to the Servlet request HTTP headers and contents
7)Map //相当于model->view
javaBean //springmvc自动绑定参数数据
9)org.springframework.validation.Errors / org.springframework.validation.BindingResult

5.@RequestMapping 方法的返回类型
@RequestMapping 方法返回的类型对象用于决定应该调用哪个view,并需要装载的model
或显示指明两者(如modelandview对象)或显示其他一个,另外一个隐式指定(如Model, View),另外一种情况是返回类型为void, 这表明handler方法内会处理返回的content,比如使用方法参数response直接写数据给客户端
以下是一些可能的返回类型
1)ModelAndView
2)Model,
3)A Map object for exposing a model
4)View
5)String 指定view name
6)void if the method handles the response itself
7)If the method is annotated with @ResponseBody,
the return type is written to the response HTTP body

6.数据绑定
@RequestMapping方法的参数都会涉及到数据绑定,比如@PathVariable, @RequestParam, JavaBean
如果数据绑定时类型不正确,会抛出异常, @RequestParam还有可选参数defaultValue, required可以稍微控制异常, 但是@PathVariable, JavaBean会直接抛异常,
springmvc解决的方式是@InitBinder, 也就spring本身的数据绑定功能,
但因为不熟spring本身的验证,绑定等功能, 一般我是自己通过request对象绑定自己的javabean

7.springmvc + freemarker
springmvc的view我使用的是freemarker引擎,在spring中配置freemarker如下:

<!-- freemarker config -->
	<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
	  <property name="templateLoaderPath" value="/WEB-INF/freemarker"/>
	   <property name="freemarkerSettings">
	       <props>
	       <prop key="defaultEncoding">UTF-8</prop>	
		   <prop key="number_format">0.#############</prop>	
		   <prop key="whitespace_stripping">true</prop>	   
	       </props>
       </property>
	</bean>
	
	<!-- Default ViewResolver -->	
	<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
	  <property name="contentType" value="text/html;charset=UTF-8" />
	  <property name="cache" value="true"/>
	  <property name="prefix" value=""/>
	  <property name="suffix" value=".ftl"/>
	</bean>

这个配置可以防止乱码问题,还有就是freemarker显示数字时,在千位是有个",",使用number_format可以去掉这个多余的","

8.redirect, forward跳转
在handler方法中,如果要进行页面跳转,返回类型设置为String
使用"redirect:"前缀,如 "redirect:/view"
相应地使用"forward:"前缀表示servlet内部跳转

9.Handling a file upload in a form
使用@RequestParam("file") MultipartFile file获取上传的文件

10.Handling exceptions处理异常

@ExceptionHandler(IOException.class)
public String handleIOException(IOException ex, HttpServletRequest request) {
    return "500";
  }


11.关于WebApplicationContext
DispatcherServlet处理一个请求时, 会将springmvc的WebApplicationContext附加到request的一个属性键值上, 这样, 每个handler都可以从request中获取这个context
属性键是DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE


12.@ResponseBody乱码问题
用@ResponseBody定义返回类型时,写入HttpResponse的内容默认编码不是utf-8,所以返回含有中文的字符串会出现乱码问题
在springmvc-config.xml配置文件下加上以下bean定义可以解决这个问题,
而且这个bean定义必须在<mvc:annotation-driven /> 之前!

<!-- fix @ResponseBody utf-8 issue should be first-->  
<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name = "messageConverters">
	<list>
	<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
           <property name = "supportedMediaTypes">
		<list>
                    <value>text/plain;charset=UTF-8</value>
		</list>
	    </property>
	</bean>
	</list>
     </property>
</bean>


13.springmvc mapping例子
假设有如下mapping:
1).@RequestMapping("/{code}")
2).@RequestMapping("/ajax/test")
请求"/test.html"会被第一个mapping拦截处理,
得出的结论是springmvc不会考虑"."以后的内容
本意是不想让第一个mapping拦截处理的,让servlet容器处理(直接返回html页面)
请求"/test/"一样会被第一个mapping拦截处理掉
但是"/test/s"就不会被第一个mapping拦截处理,servlet容器处理成404错误



...to be continued...

[/size]
分享到:
评论
3 楼 fireinjava 2012-05-24  
我以前用webwork2的,跟struts2几乎一样,很好用呀!
2 楼 naily 2012-03-06  
收藏   
1 楼 peterchao_asch 2012-02-15  
总结的不错 拜读 多谢

相关推荐

Global site tag (gtag.js) - Google Analytics