springmvc获取url参数可以做urlwrite吗

Spring Web MVC中的页面缓存支持 ——跟我学SpringMVC系列 - Spring,MVC,SpringMVC,缓存 - Java - ITeye论坛
Spring Web MVC中的页面缓存支持 ——跟我学SpringMVC系列
& 上一页 1
锁定老帖子
该帖已经被评为精华帖
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
最后修改:
相关知识库:
注:本章讲的是Spring2的
4.2、Controller接口
package org.springframework.web.servlet.
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws E
这是控制器接口,此处只有一个方法handleRequest,用于进行请求的功能处理,处理完请求后返回ModelAndView(Model模型数据部分 和 View视图部分)。
还记得第二章的HelloWorld吗?我们的HelloWorldController实现接口,Spring默认提供了一些Controller接口的实现以方便我们使用,具体继承体系如图4-1:
、WebContentGenerator
用于提供如浏览器缓存控制、是否必须有session开启、支持的请求方法类型(GET、POST等)等,该类主要有如下属性:
Set&String&
supportedMethods:设置支持的请求方法类型,默认支持“GET”、“POST”、“HEAD”,如果我们想支持“PUT”,则可以加入该集合“PUT”。
boolean requireSession = false:是否当前请求必须有session,如果此属性为true,但当前请求没有打开session将抛出HttpSessionRequiredException异常;
boolean useExpiresHeader = true:是否使用HTTP1.0协议过期响应头:如果true则会在响应头添加:“Expires:”;需要配合cacheSeconds使用;
boolean useCacheControlHeader = true:是否使用HTTP1.1协议的缓存控制响应头,如果true则会在响应头添加;需要配合cacheSeconds使用;
boolean useCacheControlNoStore = true:是否使用HTTP 1.1协议的缓存控制响应头,如果true则会在响应头添加;需要配合cacheSeconds使用;
private int cacheSeconds = -1:缓存过期时间,正数表示需要缓存,负数表示不做任何事情(也就是说保留上次的缓存设置),
1、cacheSeconds =0时,则将设置如下响应头数据:
Pragma:no-cache
// HTTP 1.0的不缓存响应头
Expires:1L
// useExpiresHeader=true时,HTTP 1.0
Cache-Control :no-cache
// useCacheControlHeader=true时,HTTP 1.1
Cache-Control :no-store
// useCacheControlNoStore=true时,该设置是防止Firefox缓存
2、cacheSeconds&0时,则将设置如下响应头数据:
Expires:System.currentTimeMillis() + cacheSeconds * 1000L
// useExpiresHeader=true时,HTTP 1.0
Cache-Control :max-age=cacheSeconds
// useCacheControlHeader=true时,HTTP 1.1
3、cacheSeconds&0时,则什么都不设置,即保留上次的缓存设置。
此处简单说一下以上响应头的作用,缓存控制已超出本书内容:
HTTP1.0缓存控制响应头
Pragma:no-cache:表示防止客户端缓存,需要强制从服务器获取最新的数据;
Expires:HTTP1.0响应头,本地副本缓存过期时间,如果客户端发现缓存文件没有过期则不发送请求,HTTP的日期时间必须是格林威治时间(GMT),如“Expires:Wed, 14 Mar :32 GMT”;
HTTP1.1缓存控制响应头
Cache-Control :no-cache
强制客户端每次请求获取服务器的最新版本,不经过本地缓存的副本验证;
Cache-Control :no-store
强制客户端不保存请求的副本,该设置是防止Firefox缓存
Cache-Control:max-age=[秒]
客户端副本缓存的最长时间,类似于HTTP1.0的Expires,只是此处是基于请求的相对时间间隔来计算,而非绝对时间。
还有相关缓存控制机制如Last-Modified(最后修改时间验证,客户端的上一次请求时间 在 服务器的最后修改时间 之后,说明服务器数据没有发生变化 返回304状态码)、ETag(没有变化时不重新下载数据,返回304)。
该抽象类默认被AbstractController和WebContentInterceptor继承。
4.4、AbstractController
该抽象类实现了Controller,并继承了WebContentGenerator(具有该类的特性,具体请看4.3),该类有如下属性:
boolean synchronizeOnSession = false:表示该控制器是否在执行时同步session,从而保证该会话的用户串行访问该控制器。
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//委托给WebContentGenerator进行缓存控制
checkAndPrepare(request, response, this instanceof LastModified);
//当前会话是否应串行化访问.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
return handleRequestInternal(request, response);
return handleRequestInternal(request, response);
可以看出AbstractController实现了一些特殊功能,如继承了WebContentGenerator缓存控制功能,并提供了可选的会话的串行化访问功能。而且提供了handleRequestInternal方法,因此我们应该在具体的控制器类中实现handleRequestInternal方法,而不再是handleRequest。
AbstractController使用方法:
首先让我们使用AbstractController来重写第二章的HelloWorldController:
public class HelloWorldController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//1、收集参数
//2、绑定参数到命令对象
//3、调用业务对象
//4、选择下一个页面
ModelAndView mv = new ModelAndView();
//添加模型数据 可以是任意的POJO对象
mv.addObject("message", "Hello World!");
//设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName("hello");
可以看出AbstractController实现了一些特殊功能,如继承了WebContentGenerator缓存控制功能,并提供了可选的会话的串行化访问功能。而且提供了handleRequestInternal方法,因此我们应该在具体的控制器类中实现handleRequestInternal方法,而不再是handleRequest。
AbstractController使用方法:
首先让我们使用AbstractController来重写第二章的HelloWorldController:
public class HelloWorldController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//1、收集参数
//2、绑定参数到命令对象
//3、调用业务对象
//4、选择下一个页面
ModelAndView mv = new ModelAndView();
//添加模型数据 可以是任意的POJO对象
mv.addObject("message", "Hello World!");
//设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName("hello");
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/hello" class="cn.javass.chapter3.web.controller.HelloWorldController"/&
从如上代码我们可以看出:
1、继承AbstractController
2、实现handleRequestInternal方法即可。
直接通过response写响应
如果我们想直接在控制器通过response写出响应呢,以下代码帮我们阐述:
public class HelloWorldWithoutReturnModelAndViewController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
resp.getWriter().write("Hello World!!");
//如果想直接在该处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloWithoutReturnModelAndView" class="cn.javass.chapter3.web.controller.HelloWorldWithoutReturnModelAndViewController"/&
从如上代码可以看出如果想直接在控制器写出响应,只需要通过response写出,并返回null即可。
强制请求方法类型:
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloWithPOST" class="cn.javass.chapter3.web.controller.HelloWorldController"&
&property name="supportedMethods" value="POST"&&/property&
以上配置表示只支持POST请求,如果是GET请求客户端将收到“HTTP Status 405 - Request method 'GET' not supported”。
比如注册/登录可能只允许POST请求。
当前请求的session前置条件检查,如果当前请求无session将抛出HttpSessionRequiredException异常:
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloRequireSession"
class="cn.javass.chapter3.web.controller.HelloWorldController"&
&property name="requireSession" value="true"/&
在进入该控制器时,一定要有session存在,否则抛出HttpSessionRequiredException异常。
Session同步:
即同一会话只能串行访问该控制器。
缓存控制:
1、缓存5秒,cacheSeconds=5
package cn.javass.chapter3.web.
//省略import
public class HelloWorldCacheController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//点击后再次请求当前页面
resp.getWriter().write("&a href=''&this&/a&");
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloCache"
class="cn.javass.chapter3.web.controller.HelloWorldCacheController"&
&property name="cacheSeconds" value="5"/&
如上配置表示告诉浏览器缓存5秒钟:
开启chrome浏览器调试工具:
服务器返回的响应头如下所示:
添加了“Expires:Wed, 14 Mar :32 GMT” 和“Cache-Control:max-age=5” 表示允许客户端缓存5秒,当你点“this”链接时,会发现如下:
而且服务器也没有收到请求,当过了5秒后,你再点“this”链接会发现又重新请求服务器下载新数据。
注:下面提到一些关于缓存控制的一些特殊情况:
1、对于一般的页面跳转(如超链接点击跳转、通过js调用window.open打开新页面都是会使用浏览器缓存的,在未过期情况下会直接使用浏览器缓存的副本,在未过期情况下一次请求也不发送);
2、对于刷新页面(如按F5键刷新),会再次发送一次请求到服务器的;
2、不缓存,cacheSeconds=0
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloNoCache"
class="cn.javass.chapter3.web.controller.HelloWorldCacheController"&
&property name="cacheSeconds" value="0"/&
以上配置会要求浏览器每次都去请求服务器下载最新的数据:
3、cacheSeconds&0,将不添加任何数据
响应头什么缓存控制信息也不加。
4、Last-Modified缓存机制
(1、在客户端第一次输入url时,服务器端会返回内容和状态码200表示请求成功并返回了内容;同时会添加一个“Last-Modified”的响应头表示此文件在服务器上的最后更新时间,如“Last-Modified:Wed, 14 Mar :42 GMT”表示最后更新时间为( 10:22);
(2、客户端第二次请求此URL时,客户端会向服务器发送请求头 “If-Modified-Since”,询问服务器该时间之后当前请求内容是否有被修改过,如“If-Modified-Since: Wed, 14 Mar :42 GMT”,如果服务器端的内容没有变化,则自动返回 HTTP 304状态码(只要响应头,内容为空,这样就节省了网络带宽)。
客户端强制缓存过期:
(1、可以按ctrl+F5强制刷新(会添加请求头 HTTP1.0 Pragma:no-cache和 HTTP1.1 Cache-Control:no-cache 、If-Modified-Since请求头被删除)表示强制获取服务器内容,不缓存。
(2、在请求的url后边加上时间戳来重新获取内容,加上时间戳后浏览器就认为不是同一份内容:
? 和 4 是两次不同的请求。
Spring也提供了Last-Modified机制的支持,只需要实现LastModified接口,如下所示:
package cn.javass.chapter3.web.
public class HelloWorldLastModifiedCacheController extends AbstractController implements LastModified {
private long lastM
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//点击后再次请求当前页面
resp.getWriter().write("&a href=''&this&/a&");
public long getLastModified(HttpServletRequest request) {
if(lastModified == 0L) {
//TODO 此处更新的条件:如果内容有更新,应该重新返回内容最新修改的时间戳
lastModified = System.currentTimeMillis();
return lastM
&!— 在chapter3-servlet.xml配置处理器 --&
&bean name="/helloLastModified"
class="cn.javass.chapter3.web.controller.HelloWorldLastModifiedCacheController"/&
HelloWorldLastModifiedCacheController只需要实现LastModified接口的getLastModified方法,保证当内容发生改变时返回最新的修改时间即可。
(1、发送请求到服务器,如(),则服务器返回的响应为:
(2、再次按F5刷新客户端,返回状态码304表示服务器没有更新过:
(3、重启服务器,再次刷新,会看到200状态码(因为服务器的lastModified时间变了)。
Spring判断是否过期,通过如下代码,即请求的“If-Modified-Since” 大于等于当前的getLastModified方法的时间戳,则认为没有修改:
this.notModified = (ifModifiedSince &= (lastModifiedTimestamp / 1000 * 1000));
5、ETag(实体标记)缓存机制
(1:浏览器第一次请求,服务器在响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,类似服务器端返回的格式:“ETag:"0f8b0c86fe2c0c7a208e3"”
(2:浏览器第二次请求,客户端的查询更新格式是这样的:“If-None-Match:"0f8b0c86fe2c0c7a208e3"”,如果ETag没改变,表示内容没有发生改变,则返回状态304。
Spring也提供了对ETag的支持,具体需要在web.xml中配置如下代码:
&filter-name&etagFilter&/filter-name&
&filter-class&org.springframework.web.filter.ShallowEtagHeaderFilter&/filter-class&
&filter-mapping&
&filter-name&etagFilter&/filter-name&
&servlet-name&chapter3&/servlet-name&
&/filter-mapping&
此过滤器只过滤到我们DispatcherServlet的请求。
1):发送请求到服务器:“”,服务器返回的响应头中添加了(ETag:"0f8b0c86fe2c0c7a208e3"):
2):浏览器再次发送请求到服务器(按F5刷新),请求头中添加了“If-None-Match:
"0f8b0c86fe2c0c7a208e3"”,响应返回304代码,表示服务器没有修改,并且响应头再次添加了“ETag:"0f8b0c86fe2c0c7a208e3"”(每次都需要计算):
那服务器端是如何计算ETag的呢?
protected String generateETagHeaderValue(byte[] bytes) {
StringBuilder builder = new StringBuilder("\"0");
DigestUtils.appendMd5DigestAsHex(bytes, builder);
builder.append('"');
return builder.toString();
bytes是response要写回到客户端的响应体(即响应的内容数据),是通过MD5算法计算的内容的摘要信息。也就是说如果服务器内容不发生改变,则ETag每次都是一样的,即服务器端的内容没有发生改变。
此处只列举了部分缓存控制,详细介绍超出了本书的范围,强烈推荐: (中文版) 详细了解HTTP缓存控制及为什么要缓存。
缓存的目的是减少相应延迟 和 减少网络带宽消耗,比如css、js、图片这类静态资源应该进行缓存。
实际项目一般使用反向代理服务器(如nginx、apache等)进行缓存。
等级: 初级会员
来自: 沈阳
发表时间:&&
LZ什么时候出个视频啥的啊?
请登录后投票
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
忙 光写文档就累死啦,只能周末和晚上写
请登录后投票
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
lc 写道LZ什么时候出个视频啥的啊?
有时间 一定会出,谢谢支持
请登录后投票
等级: 初级会员
来自: 上海
发表时间:&&
介绍的很详细,一直关注楼主的spring系列文章,非常不错。
请登录后投票
积分: 1950
来自: 长沙
发表时间:&&
写的非常不错,支持一个
请登录后投票
等级: 初级会员
来自: 上海
发表时间:&&
可惜是浏览器缓存,我还以为是服务端页面缓存呢
请登录后投票
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
feiyu86 写道介绍的很详细,一直关注楼主的spring系列文章,非常不错。
谢谢支持,继续写
请登录后投票
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
yin_bp 写道写的非常不错,支持一个
哈,谢谢啦!
请登录后投票
jinnianshilongnian
文章: 1113
积分: 2290
发表时间:&&
coollzh 写道可惜是浏览器缓存,我还以为是服务端页面缓存呢
昨天有人问这个 就把刚写的这块发上来了,不是服务端的
请登录后投票
& 上一页 1
跳转论坛:移动开发技术
Web前端技术
Java企业应用
编程语言技术博客分类:
一、SpringMVC注解入门
1. 创建web项目2. 在springmvc的配置文件中指定注解驱动,配置扫描器
&!-- mvc的注解驱动 --&
&mvc:annotation-driven /&
&!--只要定义了扫描器,注解驱动就不需要,扫描器已经有了注解驱动的功能 --&
&context:component-scan base-package="org.study1.mvc.controller" /&
&!-- 前缀+ viewName +后缀 --&
class="org.springframework.web.servlet.view.InternalResourceViewResolver"&
&!-- WebContent(WebRoot)到某一指定的文件夹的路径 ,如下表示/WEB-INF/view/*.jsp --&
&property name="prefix" value="/WEB-INF/view/"&&/property&
&!-- 视图名称的后缀 --&
&property name="suffix" value=".jsp"&&/property&
&context:component-scan/& 扫描指定的包中的类上的注解,常用的注解有:
@Controller 声明Action组件@Service
声明Service组件
@Service("myMovieLister") @Repository 声明Dao组件@Component
泛指组件, 当不好归类时. @RequestMapping("/menu")
请求映射@Resource
用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName") @Autowired 用于注入,(srping提供的) 默认按类型装配 @Transactional( rollbackFor={Exception.class}) 事务管理@ResponseBody@Scope("prototype")
设定bean的作用
3. @controller:标识当前类是控制层的一个具体的实现4. @requestMapping:放在方法上面用来指定某个方法的路径,当它放在类上的时候相当于命名空间需要组合方法上的requestmapping来访问。
@Controller // 用来标注当前类是springmvc的控制层的类
@RequestMapping("/test") // RequestMapping表示 该控制器的唯一标识或者命名空间
public class TestController {
* 方法的返回值是ModelAndView中的
@RequestMapping("/hello.do") // 用来访问控制层的方法的注解
public String hello() {
System.out.println("springmvc annotation... ");
return "jsp1/index";
在本例中,项目部署名为mvc,tomcat url为 ,所以实际为:
在本例中,因为有命名空间 /test,所以请求hello方法地址为:http://localhost/mvc/test/hello.do
输出:springmvc annotation...
二、注解形式的参数接收
1. HttpServletRequest可以直接定义在参数的列表,通过该请求可以传递参数
url:http://localhost/mvc/test/toPerson.do?name=zhangsan
* HttpServletRequest可以直接定义在参数的列表,
@RequestMapping("/toPerson.do")
public String toPerson(HttpServletRequest request) {
String result = request.getParameter("name");
System.out.println(result);
return "jsp1/index";
可以从HttpServletRequest 取出“name”属性,然后进行操作!如上,可以取出 “name=zhangsan”
输出:zhangsan2. 在参数列表上直接定义要接收的参数名称,只要参数名称能匹配的上就能接收所传过来的数据, 可以自动转换成参数列表里面的类型,注意的是值与类型之间是可以转换的
2.1传递多种不同类型的参数:
url:http://localhost/mvc/test/toPerson1.do?name=zhangsan&age=14&address=china&birthday=
* 传递的参数的名字必须要与实体类的属性set方法后面的字符串匹配的上才能接收到参数,首字符的大小写不区分
* 请求中传的参数只要是能和参数列表里面的变量名或者实体里面的set后面的字符串匹配的上就能接收到 a
@RequestMapping("/toPerson1.do")
public String toPerson1(String name, Integer age, String address,
Date birthday) {
System.out.println(name + " " + age + " " + address + " " + birthday);
return "jsp1/index";
* 注册时间类型的属性编辑器,将String转化为Date
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd"), true));
输出:zhangsan 14 china Fri Feb 11 00:00:00 CST 2000
2.2传递数组:
url:http://localhost/mvc/test/toPerson2.do?name=tom&name=jack
* 对数组的接收,定义为同名即可
@RequestMapping("/toPerson2.do")
public String toPerson2(String[] name) {
for (String result : name) {
System.out.println(result);
return "jsp1/index";
输出:tom jack
2.3传递自定义对象(可多个):
url:http://localhost/mvc/test/toPerson3.do?name=zhangsan&age=14&address=china&birthday=
User 定义的属性有:name,age,并且有各自属性的对应的set方法以及toString方法
Person定义的属性有:name,age.address,birthday,并且有各自属性的对应的set方法以及toString方法
* 传递的参数的名字必须要与实体类的属性set方法后面的字符串匹配的上才能接收到参数,首字符的大小写不区分
* 请求中传的参数只要是能和参数列表里面的变量名或者实体里面的set后面的字符串匹配的上就能接收到
@RequestMapping("/toPerson3.do")
public String toPerson3(Person person, User user) {
System.out.println(person);
System.out.println(user);
return "jsp1/index";
Person [name=zhangsan, age=14, address=china, birthday=Fri Feb 11 00:00:00 CST 2000]User [name=zhangsan, age=14]
自动封装了对象,并且被分别注入进来!
三、注解形式的结果返回
1. 数据写到页面,方法的返回值采用ModelAndView, new ModelAndView("index", map);,相当于把结果数据放到response里面
url:http://localhost/mvc/test/toPerson41.do
url:http://localhost/mvc/test/toPerson42.do
url:http://localhost/mvc/test/toPerson43.do
url:http://localhost/mvc/test/toPerson44.do
* HttpServletRequest可以直接定义在参数的列表,并且带回返回结果
@RequestMapping("/toPerson41.do")
public String toPerson41(HttpServletRequest request) throws Exception {
request.setAttribute("p", newPesion());
return "index";
* 方法的返回值采用ModelAndView, new ModelAndView("index", map);
* ,相当于把结果数据放到Request里面,不建议使用
@RequestMapping("/toPerson42.do")
public ModelAndView toPerson42() throws Exception {
Map&String, Object& map = new HashMap&String, Object&();
map.put("p", newPesion());
return new ModelAndView("index", map);
* 直接在方法的参数列表中来定义Map,这个Map即使ModelAndView里面的Map,
* 由视图解析器统一处理,统一走ModelAndView的接口,也不建议使用
@RequestMapping("/toPerson43.do")
public String toPerson43(Map&String, Object& map) throws Exception {
map.put("p", newPesion());
return "index";
* 在参数列表中直接定义Model,model.addAttribute("p", person);
* 把参数值放到request类里面去,建议使用
@RequestMapping("/toPerson44.do")
public String toPerson44(Model model) throws Exception {
// 把参数值放到request类里面去
model.addAttribute("p", newPesion());
return "index";
* 为了测试,创建一个Persion对象
public Person newPesion(){
Person person = new Person();
person.setName("james");
person.setAge(29);
person.setAddress("maami");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse("");
person.setBirthday(date);
以上四种方式均能达到相同的效果,但在参数列表中直接定义Model,model.addAttribute("p", person);把参数值放到request类里面去,建议使用
2. Ajax调用springmvc的方法:直接在参数的列表上定义PrintWriter,out.write(result);把结果写到页面,建议使用的
url:http://localhost/mvc/test/toAjax.do
* ajax的请求返回值类型应该是void,参数列表里直接定义HttpServletResponse,
* 获得PrintWriter的类,最后可把结果写到页面 不建议使用
@RequestMapping("/ajax1.do")
public void ajax1(String name, HttpServletResponse response) {
String result = "hello " +
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
* 直接在参数的列表上定义PrintWriter,out.write(result);
* 把结果写到页面,建议使用的
@RequestMapping("/ajax2.do")
public void ajax2(String name, PrintWriter out) {
String result = "hello " +
out.write(result);
* 转向ajax.jsp页面
@RequestMapping("/toAjax.do")
public String toAjax() {
return "ajax";
ajax页面代码如下:
&script type="text/javascript" src="js/jquery-1.6.2.js"&&/script&
&script type="text/javascript"&
$(function(){
$("#mybutton").click(function(){
url:"test/ajax1.do",
type:"post",
dataType:"text",
name:"zhangsan"
success:function(responseText){
alert(responseText);
error:function(){
alert("system error");
&input id="mybutton" type="button" value="click"&
四、表单提交和重定向
1、表单提交:
请求方式的指定:@RequestMapping( method=RequestMethod.POST )可以指定请求方式,前台页面就必须要以它制定好的方式来访问,否则出现405错误
表单jsp页面:
&base href="&%=basePath%&"&
&title&SpringMVC Form&/title&
&form action="test/toPerson5.do" method="post"&
name:&input name="name" type="text"&&br&
age:&input name="age" type="text"&&br&
address:&input name="address" type="text"&&br&
birthday:&input name="birthday" type="text"&&br&
&input type="submit" value="submit"&&br&
对应方法为:
* 转向form.jsp页面
@RequestMapping("/toform.do")
public String toForm() {
return "form";
* @RequestMapping( method=RequestMethod.POST)
* 可以指定请求方式,前台页面就必须要以它制定好的方式来访问,否则出现405错误 a
@RequestMapping(value = "/toPerson5.do", method = RequestMethod.POST)
public String toPerson5(Person person) {
System.out.println(person);
return "jsp1/index";
2. 重定向:controller内部重定向,redirect:加上同一个controller中的requestMapping的值,controller之间的重定向:必须要指定好controller的命名空间再指定requestMapping的值,redirect:后必须要加/,是从根目录开始
* controller内部重定向
* redirect:加上同一个controller中的requestMapping的值
@RequestMapping("/redirectToForm.do")
public String redirectToForm() {
return "redirect:toform.do";
* controller之间的重定向:必须要指定好controller的命名空间再指定requestMapping的值,
* redirect:后必须要加/,是从根目录开始
@RequestMapping("/redirectToForm1.do")
public String redirectToForm1() {
//test1表示另一个Controller的命名空间
return "redirect:/test1/toForm.do";
参考资料:
浏览 47233
浏览: 104181 次
来自: 小城市
[color=orange][/color][/size]l] ...
写的还好。
与节省内存空间
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 spring mvc url映射 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信