SpringMVC
2021-10-08 22:49:29 30 举报
AI智能生成
此思维导图包含了有关SpringMVC的注解,配置文件等必要东西
作者其他创作
大纲/内容
开发流程
导入依赖
<dependency>
<groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.6.RELEASE</version>
</dependency>
<groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.6.RELEASE</version>
</dependency>
配置核心控制器
局部参数:声明配置文件位置
<init-param>
<param-name>contextConfigLocation</param-name><param-value>classpath:mvc.xml</param-value></init-param>
<param-name>contextConfigLocation</param-name><param-value>classpath:mvc.xml</param-value></init-param>
后端控制器
配置文件
告知springmvc哪些包存在被注解的类
注册注解开发驱动
试图解析器
作用
1.捕获后端控制器的返回值="index"
2.解析:在返回的值前后拼接==>"/index.jsp"
前缀
<!--前缀-->
<property name="prefix" value=" /"></property>
<property name="prefix" value=" /"></property>
后缀
<!--后缀-->
<property name=”suffix" value=" .jsp"></property>
<property name=”suffix" value=" .jsp"></property>
跳转
请求转发
举例
@RequestMapping(" /forw" )
class ForwardController{
@RequestMapping(" /test1")
public String testForward(){
System . out . println("test forward1");
//转发跳转/views/users.jsp
// return "views/users" ;//和下一-行等价
return "forward:/views/users. jsp";
}
@RequestMapping(" /test2" )
public String testForward2(){
System . out. println("test forward2");
//转发到/forw/test1
//return”forward:test1";//相对路径(转发到本类中的test1)
//转发到/forw/test1
return "forward:/forw/test1"; //绝对路径
}
class ForwardController{
@RequestMapping(" /test1")
public String testForward(){
System . out . println("test forward1");
//转发跳转/views/users.jsp
// return "views/users" ;//和下一-行等价
return "forward:/views/users. jsp";
}
@RequestMapping(" /test2" )
public String testForward2(){
System . out. println("test forward2");
//转发到/forw/test1
//return”forward:test1";//相对路径(转发到本类中的test1)
//转发到/forw/test1
return "forward:/forw/test1"; //绝对路径
}
重定向
举例
@RequestMapping(" /redir")
class RedirectController{
@RequestMapping(" /test1")
public String testRedirect1(){
System . out. println("test redirect1");
//重定向到/redir/test1
//return " redirect:test1"; //相对路径(转发到本类中的test1)
return " redirect:/redir/test1";//绝对路径
@RequestMapping(" /test2" )
public String testRedirect2(){
System . out . println("test redirect2");
//重定向到/views/users.jsp
return "redirect:/view/user .jsp";
class RedirectController{
@RequestMapping(" /test1")
public String testRedirect1(){
System . out. println("test redirect1");
//重定向到/redir/test1
//return " redirect:test1"; //相对路径(转发到本类中的test1)
return " redirect:/redir/test1";//绝对路径
@RequestMapping(" /test2" )
public String testRedirect2(){
System . out . println("test redirect2");
//重定向到/views/users.jsp
return "redirect:/view/user .jsp";
跳转细节
1.在增删改之后,为了防止请求重复提交,重定向跳转
2.在查询之后,可以做转发跳转
Json处理
导入依赖
Jackson spr ingMVC默认的Json解决方案选择是Jackson, 所以只需要导入jackson的jar,即可使用。
<dependency>
<groupId>com. fasterxml. jackson . core</groupId>
<artifactId>j ackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<groupId>com. fasterxml. jackson . core</groupId>
<artifactId>j ackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
使用@ResponseBody
@RequestMapping(" /test1")
@ResponseBody //将handler的返回值, 转换成json(jackson) ,并将json响应给客户端。
public User hel1o1(){
System . out. println("he1lo world");
User user = new
User();
return user ;
}
@ResponseBody //将handler的返回值, 转换成json(jackson) ,并将json响应给客户端。
public User hel1o1(){
System . out. println("he1lo world");
User user = new
User();
return user ;
}
// @ResponseBody还可以用在handler的返回值 上
@RequestMapping(" /test2" )
public @ResponseBody List<User> hello2(){
System . out. println("hello world");
List<User> users = Arrays. asList(new User(),new User());
return users ;
}
@RequestMapping(" /test2" )
public @ResponseBody List<User> hello2(){
System . out. println("hello world");
List<User> users = Arrays. asList(new User(),new User());
return users ;
}
//如果返回值已经是字符串,则不需要转json,直接将字符串响应给客户端
@RequestMapping(value= " /test3" , produces =“ text/html ;charset=utf-8") //produces 防止中文乱码
@ResponseBody
public String hello2(){
System . out. println("hello world");
return "你好";
}
@RequestMapping(value= " /test3" , produces =“ text/html ;charset=utf-8") //produces 防止中文乱码
@ResponseBody
public String hello2(){
System . out. println("hello world");
return "你好";
}
使用@RestController
Controller类上加了@RestController注解,等价于在类中的每个方法上都加了@ResponseBody
@Controller
@RestController
public class JsonController{
@RequestMapping(" /test1")
public User hello1(){
System . out. println("hello world");
User user = new User();
return user ;
}
/ /@Re sponseBody还可以用在handler的返回值上
@RequestMapping(" /test2" )
public List<User> he1lo2(){
System. out . println("hello world");
List<User> users = Arrays. asList(new User(),new User());
return users;
@RestController
public class JsonController{
@RequestMapping(" /test1")
public User hello1(){
System . out. println("hello world");
User user = new User();
return user ;
}
/ /@Re sponseBody还可以用在handler的返回值上
@RequestMapping(" /test2" )
public List<User> he1lo2(){
System. out . println("hello world");
List<User> users = Arrays. asList(new User(),new User());
return users;
使用@RequestBody
1.定义handler
class User{
private Integer id;
private String name;
private Boolean gender ;
//set get
}
@RequestMapping(" /users")
public String addUser(@RequestBody User user){/ /@RequestBody将请求体中的j son数据转换为java对象
System. out. println("cap2");
System . out . println("Post user :"+user);
return "index" ;
}
private Integer id;
private String name;
private Boolean gender ;
//set get
}
@RequestMapping(" /users")
public String addUser(@RequestBody User user){/ /@RequestBody将请求体中的j son数据转换为java对象
System. out. println("cap2");
System . out . println("Post user :"+user);
return "index" ;
}
2.Ajax发送json
var xhr = new XMLHttpRequest();
xhr . open(“post"," $ {pageContext . request . contextPath}/users?"+new Date() . getTime());
xhr . setRequestHeader(" content- type" , "application/json");//设置请求头
xhr . send(' {"id" :1,"name" :" shine",“gender":"true"}');//传递json串
//ajax
var user = {id:1, name:"shine"};
$.ajax({
url:'${pageContext . request . contextPath}/json2/test4',
type:'post',
contentType:"application/json",//声明请求参数类型为json
data:JSON. stringify(user),//转换js对象成json
success :function(ret){
console.1og(ret);
});
xhr . open(“post"," $ {pageContext . request . contextPath}/users?"+new Date() . getTime());
xhr . setRequestHeader(" content- type" , "application/json");//设置请求头
xhr . send(' {"id" :1,"name" :" shine",“gender":"true"}');//传递json串
//ajax
var user = {id:1, name:"shine"};
$.ajax({
url:'${pageContext . request . contextPath}/json2/test4',
type:'post',
contentType:"application/json",//声明请求参数类型为json
data:JSON. stringify(user),//转换js对象成json
success :function(ret){
console.1og(ret);
});
Jackson常用注解
日期格式化
@JsonFormat(pattern-="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public class User{
private Integer id;
private String name;
@JsonFormat( pattern= "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8" )
private Date birth;
get/set
}
private Integer id;
private String name;
@JsonFormat( pattern= "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8" )
private Date birth;
get/set
}
属性名修改
@JsonProperty("new_ name")
public class User{
@JsonProperty("new_ id") //不再使用原属性名,而是"new_ .id"
private Integer id;
private String name ;
get/set
}
输出的json: {"new_ id" :xx, "name":"xx"}
@JsonProperty("new_ id") //不再使用原属性名,而是"new_ .id"
private Integer id;
private String name ;
get/set
}
输出的json: {"new_ id" :xx, "name":"xx"}
属性忽略
@JsonIgnore
public class User{
private Integer id;
@JsonIgnore //生成j son时,忽略此属性
private String name;
get/set
}
输出json时: {"id" :xx}
private Integer id;
@JsonIgnore //生成j son时,忽略此属性
private String name;
get/set
}
输出json时: {"id" :xx}
null和empty属性排除
Jackson默认会输出null值的属性,如果不需要,可以排除。
@Jsonlnclude(JsonInclude.Include.NON_ NULL) /ull值属性不输出@JsonIncludel(value= Jsonlnclude.Include.NON EMPTY) // empty属性
不输出(空串,长度为0的集合,null值)
不输出(空串,长度为0的集合,null值)
public class User{
private Integer id;
@JsonInclude( JsonInclude . Include . NON NULL) // 若”name==null"忽略此属性
private String name;
@JsonInclude( value= JsonInclude . Include . NON_ EMPTY) // 若hobby长度 为0或==null忽略此属性
private List<String> hobby;
get/set
如果name=null,且hobby长度为0, 则输出json时: {"id" :xx}
private Integer id;
@JsonInclude( JsonInclude . Include . NON NULL) // 若”name==null"忽略此属性
private String name;
@JsonInclude( value= JsonInclude . Include . NON_ EMPTY) // 若hobby长度 为0或==null忽略此属性
private List<String> hobby;
get/set
如果name=null,且hobby长度为0, 则输出json时: {"id" :xx}
自定义序列化
@JsonSerialize(using = MySerializer.class) //使用MySerializer输出某属性
public class User {
private Integer id;
private String name;
@JsonSerialize(using = MySerializer .class)
private Double salary = 10000 .126;//在输出此属性时,使用MySerializer输出
get/set
则输出json时: {"id" :xx, "name" :"xxX", "salary" :10000.13}
private Integer id;
private String name;
@JsonSerialize(using = MySerializer .class)
private Double salary = 10000 .126;//在输出此属性时,使用MySerializer输出
get/set
则输出json时: {"id" :xx, "name" :"xxX", "salary" :10000.13}
public class MySerializer extends JsonSerializer<Double> {
// value即Double salary的值
@Override
public void serialize(Double value, JsonGenerator gen,SerializerProvider serializers) throws IOException {
//将Double salary的值 四舍五入
String number = BigDecimal . value0f (value) . setScale(2,BigDecimal . ROUND HALF UP) . toString();
//输出四舍五入后的值
gen. writeNumber (number);
// value即Double salary的值
@Override
public void serialize(Double value, JsonGenerator gen,SerializerProvider serializers) throws IOException {
//将Double salary的值 四舍五入
String number = BigDecimal . value0f (value) . setScale(2,BigDecimal . ROUND HALF UP) . toString();
//输出四舍五入后的值
gen. writeNumber (number);
FastJson
导入依赖
<dependency>
<groupId>com. alibaba< /groupId>
<artifactId>fastjson< /artifactId>
<version>1 .2. 54</version>
</dependency>
<groupId>com. alibaba< /groupId>
<artifactId>fastjson< /artifactId>
<version>1 .2. 54</version>
</dependency>
安装FastJson
<MVc :annotation-dr iven>
<!-- 安装FastJson,转换器-->
<mVc :message - converters>
<bean class= “com. alibaba . fastj son . support . spring. FastJsonHttpMessageConverter">
<!--声明转换类型:json -->
<property name=" supportedMediaTypes">
<list>
<value>application/json< /value>
</list>
</property>
< /bean>
< /mvc :message- converters>
< /mvc : annotation-dr iven>
<!-- 安装FastJson,转换器-->
<mVc :message - converters>
<bean class= “com. alibaba . fastj son . support . spring. FastJsonHttpMessageConverter">
<!--声明转换类型:json -->
<property name=" supportedMediaTypes">
<list>
<value>application/json< /value>
</list>
</property>
< /bean>
< /mvc :message- converters>
< /mvc : annotation-dr iven>
使用
@ResponseBody @RequestBody @RestController使用方法不变
常用注解
日期格式化
@JSONField(format*"yyy/MM/dd")
属性名修改
@JSONField(name="birth")
忽略属性
@JSONField(serialize = false)
包含null值
@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue)默认会忽略所有null值,有此注解会输出null
@JSONField(serialzeFeatures = SerializerFeature.WriteNullStringAsEmpty) null的String输出为""
自定义序列化
@JSONField(serializeUsing = MySerializer2.class)
MVC架构
概念
Model
模型:即业务模型,负责完成业务中的数据通信处理,对应项目中的service和dao
View
视图:渲染数据,生成页面。对应项目中的Jsp
Controller
控制器:直接对接请求,控制MC流程,调度模型,选择视图。对应项目中的Servlet
好处
1.MVC是现下软件开发中的最流行的代码结构形态
2.人们根据负责的不同逻辑,将项目中的代码分成MVC3个层次
3.层次内部职责单一,层次之间耦合度低
4.符合低耦合 高内聚的设计理念,也实际有利于项目而长期维护
接受请求参数
基本数据类型
请求参数和方法的形参同名即可
springmvc默认可以识别的日期字符串格式为:YYYY/MM/dd HH:mm:ss通过@DateTimeFormat可以修改默认日志格式
举例
// id
name gender
// http://localhost : 8989/xxx/ .. /test1?id=1&name=zzz&gender=false&birth-2018-12-12 12 :20 :30
@RequestMapping(" /test1")
public String testParam1 (Integer id,
String name,
Boolean gender,
@DateTimeFormat ( pattern="yyyy-MM-dd HH :mm:ss")Date birth) {
System. out. print1n("test param1");
return” index" ;
name gender
// http://localhost : 8989/xxx/ .. /test1?id=1&name=zzz&gender=false&birth-2018-12-12 12 :20 :30
@RequestMapping(" /test1")
public String testParam1 (Integer id,
String name,
Boolean gender,
@DateTimeFormat ( pattern="yyyy-MM-dd HH :mm:ss")Date birth) {
System. out. print1n("test param1");
return” index" ;
实体收参
请求参数和实体的属性同名即可
举例
public class User {
private Integer id;
private String name ;
@DateTimeFormat(pattern='”yyy-MM-dd" )
private Date birth;
private Boolean gender ;
//set/get ...
}
//http://localhost :8989/ ... /test2?id=1&name=zzz&gender=false&birth=2018-12-12 12 :20:30
@RequestMapping(" /test2")
public String testParam2(User user){
System. out. println("test param2");
System . out. println("user:" +user);
return "index" ;
}
private Integer id;
private String name ;
@DateTimeFormat(pattern='”yyy-MM-dd" )
private Date birth;
private Boolean gender ;
//set/get ...
}
//http://localhost :8989/ ... /test2?id=1&name=zzz&gender=false&birth=2018-12-12 12 :20:30
@RequestMapping(" /test2")
public String testParam2(User user){
System. out. println("test param2");
System . out. println("user:" +user);
return "index" ;
}
数组收参
简单类型的数组
举例
<form>
......
<input type=" checkbox" name= ”hobby" value="fb" />足球
<input type=" checkbox" name=" hobby" value="bb" />篮球
<input type=" checkbox" name= ”hobby" value="vb" />排球
</form>
//http://localhost:8989/ .../test3?hobby=football&hobby=basketball
@RequestMapping(" /test3")
public String testParam3 (String[] hobby){
for(String h:hobby){
System. out. print(h+" ");
}
return " index" ;
}
......
<input type=" checkbox" name= ”hobby" value="fb" />足球
<input type=" checkbox" name=" hobby" value="bb" />篮球
<input type=" checkbox" name= ”hobby" value="vb" />排球
</form>
//http://localhost:8989/ .../test3?hobby=football&hobby=basketball
@RequestMapping(" /test3")
public String testParam3 (String[] hobby){
for(String h:hobby){
System. out. print(h+" ");
}
return " index" ;
}
集合收参
举例
public class UserList {
//private User[] users;
private List<User> users;
//set/get. .
}
// <input type="text" name="users[0] .id"/>
// post请求: http://...?users[0] . id=1&users[0] .name=zhangsan&users[0]. birth=2018-12-12&users[1] . id=2&.
@RequestMapping(" /test4")
public String testPar am4(UserList userList){
for(User user :userList . getUsers()){
System. out. println(user);
return "index" ;
}
//private User[] users;
private List<User> users;
//set/get. .
}
// <input type="text" name="users[0] .id"/>
// post请求: http://...?users[0] . id=1&users[0] .name=zhangsan&users[0]. birth=2018-12-12&users[1] . id=2&.
@RequestMapping(" /test4")
public String testPar am4(UserList userList){
for(User user :userList . getUsers()){
System. out. println(user);
return "index" ;
}
路径参数
举例
// {id} 定义名为id的路径; [/hello/{id}] 的匹配能力和[/hello/*] 等价
// http://localhost :8989/... /he1lo/10 {id}匹配到10
@RequestMapping(" /hello/{id}")
// @PathVariable将 {id }路径匹配到值赋给id参数
//路径名和参数名相同则@PathVariable(" id" )可简写为@PathVariable
public String testParam5(@PathVariable("id") Integer id){
System. out. print1n("id:"+id);
return " index" ;
}
// http://localhost :8989/.. /hello/tom
{username }匹配到tom
@RequestMapping(" /he1lo/ {username }")
public String testParam6 (@PathVariable("username") String name) {/ /将{username }路径匹配到的值赋给name参数
System. out . println("username:" +name);
return " index" ;
// http://localhost :8989/... /he1lo/10 {id}匹配到10
@RequestMapping(" /hello/{id}")
// @PathVariable将 {id }路径匹配到值赋给id参数
//路径名和参数名相同则@PathVariable(" id" )可简写为@PathVariable
public String testParam5(@PathVariable("id") Integer id){
System. out. print1n("id:"+id);
return " index" ;
}
// http://localhost :8989/.. /hello/tom
{username }匹配到tom
@RequestMapping(" /he1lo/ {username }")
public String testParam6 (@PathVariable("username") String name) {/ /将{username }路径匹配到的值赋给name参数
System. out . println("username:" +name);
return " index" ;
中文乱码
1.页面中字符集统一
2.tomcat中字符集设置,对get请求中,对中文乱码参数有效
3.设置此filter,对中文乱码参数有效
举例
<!--此过滤器会进行: request. setCharactorEncoding("utf-8"); -->
<filter>
<filter-name> encoding< / filter-name>
<filter-class>org. springframework . web . filter .CharacterEncodingFilter</filter-class>
<init-param>
<par am-name> encoding</ par am-name>
<param-value>utf-8</ param-value>
</init-par am>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name> encoding< / filter-name>
<filter-class>org. springframework . web . filter .CharacterEncodingFilter</filter-class>
<init-param>
<par am-name> encoding</ par am-name>
<param-value>utf-8</ param-value>
</init-par am>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
静态资源
静态资源问题
静态资源:html,js文件,css文件,图片文件
静态文件中没有urrl-pattern,所以默认访问不到,之所以可以访问,是因为,tomcat中有一个全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是"/",是全局默认的Servlet,所以每个项目中不能匹配的静态资源的请求,有这个servlet来处理即可,但是,在springmvc中dispatcherservlet也采用了"/"作为url-parttern,则项目中不会再使用全局的Servlet,则静态资源不能完成访问
解决方案1
Dispathcer采用其他的url-pattern,此时,所有访问handler的路径都要以action结尾
<servlet>
<servlet-name>mvc9</servlet -name>
<servlet-class>org. spr ingf r amework . web. servlet . DispatcherServlet</servlet-class>
</servlet>
<servlet -mapping>
<servlet-name>mvc9< /servlet-name>
<url-pattern>* . action</url-pattern>
</servlet -mapping>
<servlet-name>mvc9</servlet -name>
<servlet-class>org. spr ingf r amework . web. servlet . DispatcherServlet</servlet-class>
</servlet>
<servlet -mapping>
<servlet-name>mvc9< /servlet-name>
<url-pattern>* . action</url-pattern>
</servlet -mapping>
解决方案2
DispathcerServlet的url-pattern依然采用"/",但追加配置
< !--
额外的增加一个handler,且其requestMapping: " /**"可以匹配所有请求,但是优先级最低
所以如果其他所有的handler都匹配不上,请求会转向“ /**”, 恰好,这个handler就是处理静态资源的
处理方式:将请求转会到tomcat中名为default的Servlet
<mvc :default-servlet-handler/>
额外的增加一个handler,且其requestMapping: " /**"可以匹配所有请求,但是优先级最低
所以如果其他所有的handler都匹配不上,请求会转向“ /**”, 恰好,这个handler就是处理静态资源的
处理方式:将请求转会到tomcat中名为default的Servlet
<mvc :default-servlet-handler/>
解决方案3
. mapping是访问路径,location是静态资源存放的路径
将/htm/** 中/**匹配到的内容,拼接到/hhh/后htp./...html/a.htmtl访问/hhh/a.html
拦截器
作用
抽取handler中的冗余功能
定义拦截器
执行顺序
preHandle--postHandle--afterCompletion
举例
在handler之前执行:抽取handler中的冗余代码
@Override
public boolean preHandle (HttpServletRequest request ,
Ht tpServletResponse response, object handler) throws Exception {
System . out . println("pre~~~");
/*
response . sendRedirect(" /spr ingMVC. day2/index. jsp");//响应
return false;//中断请求
*/
return true;//放行, 后续的拦截器或handler就会执行
}
在handler之后执行:进一步的响应定制
@Override
public void postHandle(HttpServletRequest request ,
HttpServletResponse response, object handler ,
ModelAndView modelAndView) throws Exception{
System . out . println("post~~");
}
public void postHandle(HttpServletRequest request ,
HttpServletResponse response, object handler ,
ModelAndView modelAndView) throws Exception{
System . out . println("post~~");
}
在页面渲染完毕之后执行:资源回收
@Override
public void afterCompletion( HttpServletRequest request,
HttpServletResponse response, object handler, Exception ex)
throws Exception {
System . out. println("after~~");
}
public void afterCompletion( HttpServletRequest request,
HttpServletResponse response, object handler, Exception ex)
throws Exception {
System . out. println("after~~");
}
配置拦截路径
<mvc :interceptors>
<mvc :interceptor>
<mvc :mapping path=" /inter/test1"/>
<mvc :mapping path=" /inter/test2" />
<mvc :mapping path=" /inter/test*"/> <!-- test开头-->
<mvc :mapping path=" /inter/**"/> <!-- /** 任意多级任意路径-->
<mvc :exclude-mapping path=" /inter/a/**"/> <!--不拦截此路径-->
<bean class=" com. baizhi . interceptor . MyInter1"></bean> < !--拦截器类-->
< /mvc : interceptor>
< /mvc :interceptors>
<mvc :interceptor>
<mvc :mapping path=" /inter/test1"/>
<mvc :mapping path=" /inter/test2" />
<mvc :mapping path=" /inter/test*"/> <!-- test开头-->
<mvc :mapping path=" /inter/**"/> <!-- /** 任意多级任意路径-->
<mvc :exclude-mapping path=" /inter/a/**"/> <!--不拦截此路径-->
<bean class=" com. baizhi . interceptor . MyInter1"></bean> < !--拦截器类-->
< /mvc : interceptor>
< /mvc :interceptors>
0 条评论
下一页