springmvc 笔记

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

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

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

<!-- 定义扫描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/"/>

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

@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"
[b]//"/user/login/{user}"中的user不能是中文,应该跟springmvc默认编码有关[/b]


[size=medium][b]4.@RequestMapping 方法的参数类型[/b]
@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
8)javaBean //springmvc自动绑定参数数据
9)org.springframework.validation.Errors / org.springframework.validation.BindingResult

[b]5.@RequestMapping 方法的返回类型[/b]
@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

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

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

<!-- 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>

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

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

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

[b]10.Handling exceptions处理异常[/b][/size]

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

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


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

<!-- 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>


[b]13.springmvc mapping例子[/b]
假设有如下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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值