SpringMVC
文章目录
详细讲解
转发和重定向
- SpringMVC的默认的方式是转发,不是重定向
- 重定向相当于两次请求,会丢失原有的请求状态
-
修改原有的类
重定向 相当于重新发起一次请求
在webapp下有一个temp.jsp
/是类路径下 还可以重定向到其他的请求,这个和Web是一样的
可以看到 第一次请求的数据没有带过来
同样的 forword也可以带forward:/~ 到其他的页面
SpringMVC访问web元素
request
WebRequest 这是SpringMvc模拟的一个Request 并不是原生的request
键入URL : http://localhost:8080/web/request?goddess="LiuYiFei"
控制台打印
获得原生request
结果也是相同, 但是原生的request在意义上是基于HTTP请求方式的
session
添加方法 且使用重定向
如果是请求就会丢失原请求的状态
application
这个也同理不做过多的演示
RequestMapping注解
先来看一下源码里都有什么
- value可以有多个也就是意味着 可以有映射多个请求
- path是value的别名, 二者任选其一.结果是一样的
-
method 它的类型是RequestMethod 它的类型是一个枚举 且method是一个数组意味着也有多个 如果不显式的指定 啥请求都可以
小技巧
使用一个初始化的Servlet存储上下文路径
这样请求路径的时候只用写${ctx}就可以了
更改项目名称也不用变
method 可以限定访问的方式 如果是GET 那么POST及其他的方式进不来
例如 下面这个例子 如果去除method 那么就有两个对k1的映射 就会抛出服务器的异常
但是下面指定一个接受POST方法 一个接受GET方法 就只会去GET方法
所以会进入到goddess.jsp
当然这也可以写成一个数组形式
-
params
像这样 如果直接请求会到k4里 你的url带上参数username和password才会请求到k3
当然可以指定这个参数必定是什么 -
headers
这个道理和params一样 指定header必须是什么才接受 -
consumers
请求的媒体类型, 可以限定application/json;charset=UTF-8 -
produces
和上面的相对应 响应的媒体类型
关于请求路径
springMVC支持ant风格
- ?:任意字符, 斜杠除外 例如请求的映射是/k? 键入/k不行 /k1 /k2 /ka…都可以匹配成功
- *:任意个字符都可以, 不能含有斜杠
- **:支持多层路径 例如/k/**这样后面可以跟多个层路径
其他Mapping
- @GetMapping: 限定了只支持GET请求
-
@PostMapping:限定了只支持POST请求
对于非get post请求的支持
需要有额外的内容添加, 需要添加一个过滤器
但是到现在还是不能用
需要在表单页面里面添加一个隐藏字段
先看一下方法
表单里面 看清楚 隐藏字段的name必须写_method
点击后就会打印
为什么必须是_method
这是人家的约束
关于静态资源访问的问题(重要)
-
由于我们的Servlet设置了URL匹配方式为/ 所以,它将静态资源也当做一个后台的请求
比如说 在一个html页面里面link了css的文件 他就会把这个.css文件当做是一个请求,去找Controller里面的映射, 因为没有所以会出现404
所以你需要去SpringMVC配置文件 注册驱动 这个东西的功能很强大 一般写项目都需要配置这个
-
也可以一个个去配置 不过不推荐
@PathVariable
这种用法是一种REST风格[这个可以去自行百度一下]
写了一个控制器
然后URL
打印
其实就是可以把对应名字的参数拿下来
@Responsebody
返回数据的, 一般情况下返回JSON格式
可以用作返回Java的对象到页面
然后看一下结果
其实等价于那种response.getWriter的方式一样
POST中文乱码的问题
- 以前添加一个过滤器即可
- springMVC提供了非常好的字符编码过滤器, 注册即可
- 在Web.xml中添加
-
最好把处理编码的过滤器放到前面
 - 贴一下代码
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
form表单和POJO
-
通过属性名称可以绑定数据
例如 页面
注意 这两个名字必须一致 不然无法绑定
输入zhangSan提交 可以得到数据 -
如果参数是多个呢 可以封装一个POJO
User类
修改表单 注意表单的name和User类
跳转到页面
打印结果
当然你也可以 多使用几个参数 但是如果有必要封装成一个pojo的时候就应当封装一个pojo
-
如果当名字不一样的时候呢?
比如form表单是这样的
控制器是这样的
这样就传不过来
所以应该使用下面
表单
结果显示
但是这里默认的日期类型是无法转的
User类有个Date数据
这样得到的就会是null
@InitBinder
- 由@initBinder表示的方法可以做一些初始化的工作
- 用于完成表单字段到JavaBean属性的绑定
- @InitBinder方法不能有返回值, 它必须声明为void
-
@InitBinder方法的参数通常是WebDataBinder
当然还有这种方式 可以自己试一下
@ModelAttribute
在controller里面的任意个一个处理具体的方法之前都会执行
在运行put前 init方法先运行了
且这个映射器里的所有映射执行前都会执行init方法
修改方法
这样也是可以的
如果使用这个注解
已经在模型里面添加了数据
如果在前端提交了数据 会替换掉模型里面的数据
这个注解也可以修饰目标方法的POJO的入参
如果在请求数据中有一个名为abc的user对象 这个注解标记的value 写成 abc 这样入参也可以传进去
这里还可能引发一个异常 如果你的这个注解作为了方法入参 且value值所对应在数据中没有 并且类上有@SessionAttributes注解且注解里有个value和ModelAttribute的注解的value一样
**这样是没问题的 **
此时就产生了异常 尽量避免这样使用
@SessionAttributes
新的控制器类
页面
因为这里在请求的模型数据里面保存了一份 因为名称和类型匹配了session中的数据 所以也会保存在session中
@SessionAttribute
SessionAttribute 当你的会话中有这个数据 并且同名 就可以获取到 其实个RequestParam大同小异