spring MVC

先备份一下。
[url]http://elf8848.iteye.com/blog/875830[/url]

以下是《Spring Framework Reference Documentation》3.2.1学习笔记
目标 [color=red]在mvc-ajax示例代码的基础上完成订单提交部分的异步验证功能[/color]
已完成[color=darkblue]在mvc-basic示例基础上实现完整的web侧订单(包括子项目)录入,支持国际化[/color]


[b]web.xml中配置org.springframework.web.servlet.DispatcherServlet。也可以以编码方式配置。[/b]

org.springframework.web.servlet包中的DispatcherServlet.properties描述了DispatcherServlet维护的一组对特殊bean的默认实现。

WebAplicationContext在ServletContext中
通过RequestContextUtils的静态方法可以获得WebAplicationContext

[b]实现Controllers[/b]

[quote]@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
// implementation omitted
}
Or if the URI template variable name matches the method argument name you can omit that
detail.[/quote]
如果URL模板变量名和方法参数变量名相同,可以省略@PathVariable注解中的变量名字符串。

[quote]A method can have any number of @PathVariable annotations[/quote]
一个方法可以有任意多个@PathVariable注解。

[quote]When a @PathVariable annotation is used on a Map<String, String> argument, the map is
populated with all URI template variables.[/quote]
@PathVariable注解用于Map<String, String>类型的参数时,URL模板变量将自动映射到map参数中。

[quote]A URI template can be assembled from type and path level @RequestMapping annotations. As a result
the findPet() method can be invoked with a URL such as /owners/42/pets/21[/quote]
URL模板可以由类级别和方法级别的@RequestMapping注解组合而成:如
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model
model) {
// implementation omitted
}
}

findPet() 方法可以这样访问 /owners/42/pets/21

@RequestMapping注解支持正则表达式。语法为:{varName:regex}。用法如:
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {
// ...
}
}

访问路径可能为:"/spring-web/spring-web-3.0.5.jar"


配置<context:component-scan base-package="*.web"/>来让spring自动发现添加了@Controller注解的类。

可以对Controller进行范围缩小,如:
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
中的consumes="application/json"条件

@Controller
@RequestMapping(value = "/pets/{petId}", method =
RequestMethod.GET, produces="application/json")
@ResponseBody //指定用来生成response
public Pet getPet(@PathVariable String petId, Model model) {
// implementation omitted
}

@RequestMapping(value = "/pets/{petId}", method =
RequestMethod.GET, params="myParam=myValue") //这里的params参数
//该参数内容可以是"myParam", "!myParam", or "myParam=myValue".
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model
model) {
// implementation omitted
}


使用@RequestParam参数绑定request参数到方法参数。如:
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="myHeader=myValue")
//这里通过对请求header中的属性和值进行过滤
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model
model) {
// implementation omitted
}


定义@RequestMapping处理方法
@RequestMapping处理方法支持的一批参数,见“Supported method argument types”部分

Errors 或者 BindingResult参数必须紧跟@ModelAttribute注解的参数,
下面的BindingResult result参数应该移到pet参数后面。
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet,
Model model, BindingResult result) { … }
@ModelAttribute参数可能会有多个,spring会为每一个这种对象生成一个 BindingResult


使用@RequestBody映射request body
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
writer.write(body);
}


使用@ResponseBody映射response body
@RequestMapping(value = "/something", method = RequestMethod.PUT)
@ResponseBody
public String helloWorld() {
return "Hello World";
}


使用 HttpEntity<?>
HttpEntity被允许访问request 和response body
@RequestMapping("/something")
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws
UnsupportedEncodingException {
String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader"));
byte[] requestBody = requestEntity.getBody();
// do something with request header and body
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}


在方法上使用@ModelAttribute
// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
// Add multiple attributes
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
model.addAttribute(accountManager.findAccount(number));
// add more ...
}


方法参数中使用@ModelAttribute
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) {
}


@RequestMapping(value="/accounts/{account}", method = RequestMethod.PUT)
public String save(@ModelAttribute("account") Account account) {
}


JSR-303 @Valid annotation验证
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {
if (result.hasErrors()) {
return "petForm";
}
// ...
}


使用@SessionAttributes保存model属性到session
@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
// ...
}

如果使用controller接口,则@RequestMapping and @SessionAttributes这些注解应该放在接口中。


使用@CookieValue映射cookie属性
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) {
//...
}


使用@RequestHeader 映射request header属性
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
//...
}


自定义参数类型转换见“Customizing WebDataBinder initialization”章节或者7.6节
使用@InitBinder自定义数据绑定
@Controller
public class MyFormController {
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
// ...
}


异步请求处理。返回Callable
@RequestMapping(method=RequestMethod.POST)
public Callable<String> processUpload(final MultipartFile file) {
return new Callable<String>() {
public Object call() throws Exception {
// ...
return "someView";
}
};
}


用来响应JMS等外部事件的请求
@RequestMapping("/quotes")
@ResponseBody
public DeferredResult<String> quotes() {
DeferredResult<String> deferredResult = new DeferredResult<String>();
// Save the deferredResult in in-memory queue ...
return deferredResult;
}
// In some other thread...
deferredResult.setResult(data);


使用HandlerInterceptor拦截请求,实现自定义的对请求的拦截。
可以继承HandlerInterceptorAdapter来简化自定义实现。
见Intercepting requests with a HandlerInterceptor章节。


对View的处理
spring提供的View处理器
AbstractCachingViewResolver 抽象类。是其它具体处理器的父类。扩展该处理器可提供缓存。
XmlViewResolver
ResourceBundleViewResolver 可以用于配置处理多种视图处理方式。比如配置某些url使用某种处理器。
UrlBasedViewResolver 可以处理jsp视图。是AbstractCachingViewResolver 的子类。
InternalResourceViewResolver 可以处理Servlets and JSPs。是UrlBasedViewResolver 的子类。
VelocityViewResolver /FreeMarkerViewResolver
ContentNegotiatingViewResolver


视图处理器链
需要注意的是InternalResourceViewResolver处理器应该配置在最后,
或者说要让InternalResourceViewResolver处理器做最后的尝试。
因为InternalResourceViewResolver始终会返回一个视图,一旦返回,其它视图处理器就不会再处理了。


视图重定向
一般情况下,一个controller接受到一个请求后会返回一个逻辑视图名称然后交由特定的视图处理器处理。
但是有些情况需要在视图被渲染以前重定向到客户端。
比如,防止用户刷新页面时造成表单重提交。
再比如,将post请求交给其它controller继续处理。(这部分需要实践加深理解了)
URL模板变量在重定向时是可以直接使用的。

使用flash属性
建议只在重定向时使用。一般的请求也不需要使用该属性。
FlashMap用来保存flash属性。可通过RequestContextUtils的静态方法获取FlashMap。


使用locaels
通过RequestContext.getLocale()可以获取locale处理器处理后的locale


以下是spring提供的国际化处理器:
AcceptHeaderLocaleResolver
该处理器会检查请求中的“accept-language” 头信息。通常为操作系统的locale信息。
CookieLocaleResolver

该处理器会检查请求中的“accept-language” 头信息。
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieName" value="clientlanguage"/>
<!-- in seconds. If set to -1, the cookie is not persisted (deleted when browser shuts
down) -->
<property name="cookieMaxAge" value="100000">
</bean>

SessionLocaleResolver
从locale获取locale


LocaleChangeInterceptor
配置拦截器来处理国际化(也是spring官方示例中使用的配置)
<!-- Configures Handler Interceptors -->
<mvc:interceptors>
<!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>
教程中的示例
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="siteLanguage"/><!-- siteLanguage为请求中的参数名称 -->
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor"/>
</list>
</property>
<property name="mappings">
<value>/**/*.view=someController</value>
</property>
</bean>


spring对文件上传的支持
基于commons-fileupload.jar的文件上传
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
导入commons-fileupload.jar

基于Servlet 3.0的文件上传
在web.xml中配置"multipart-config" 部分
配置
<bean id="multipartResolver"
class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

页面部分
<html>
<head>
<title>Upload a file please</title>
</head>
<body>
<h1>Please upload a file</h1>
<form method="post" action="/form" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
</body>
</html>

controller部分
@Controller
public class FileUploadController {
@RequestMapping(value = "/form", method = RequestMethod.POST)
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
} else {
return "redirect:uploadFailure";
}
}
}
如果是使用Servlet3.0可以用javax.servlet.http.Part
@Controller
public class FileUploadController {
@RequestMapping(value = "/form", method = RequestMethod.POST)
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") Part file) {
InputStream inputStream = file.getInputStream();
// store bytes from uploaded file somewhere
return "redirect:uploadSuccess";
}
}


Convention配置
没有struts2的零配置好用


配置默认首页
<!-- web.xml中配置首页 这种方式在处理国际化时会有些问题-->
<welcome-file-list>
<welcome-file>/WEB-INF/views/account/welcome.jsp</welcome-file>
</welcome-file-list>

DispatcherServlet的配置文件中配置首页
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:view-controller path="/" view-name="account/welcome"/>


静态资源的配置
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/public-web-resources/"/>

表示通过http://.../resources/**路径访问时
将可以在项目的根路径或者jar包中的META-INF/public-web-resources/路径下找到资源文件。
在比如
<mvc:resources mapping="/resources/**" location="/resources/,/WEB-INF/js/" />

可以将js文件放在项目的/WEB-INF/js/目录下。然后再jsp文件中访问
<script src="<c:url value="/resources/jquery.min-1.9.1.js" />"></script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值