springmvc

一、SpringMVC

1.1 引言1.2 MVC架构1.2.1 概念1.2.2 好处

二、开发流程

2.1 导入依赖2.2 配置核心(前端)控制器2.3 后端控制器2.4 配置文件2.5 访问

三、接收请求参数

3.1 基本类型参数3.2 实体收参【重点】3.3 数组收参3.4 集合收参 【了解】3.5 路径参数3.6 中文乱码

四、跳转

4.1 转发4.2 重定向4.3 跳转细节

五、传值

5.1 Request和Session5.2 JSP中取值5.3 Model5.4 ModelAndView5.5 @SessionAttributes

六、静态资源

6.1 静态资源问题6.2 解决方案16.3 解决方案26.4 解决方案3

七、Json处理

7.1 导入依赖7.2 使用@ResponseBody7.3 使用@RestController7.4 使用@RequestBody7.4.1 定义Handler7.4.2 Ajax发送json7.5 Jackson常用注解7.5.1 日期格式化7.5.2 属性名修改7.5.3 属性忽略7.5.4 null和empty属性排除7.5.5 自定义序列化7.6 FastJson7.6.1 导入依赖7.6.2 安装FastJson7.6.3 使用7.6.4 常用注解

八、异常解析器

8.1 现有方案,分散处理8.2 异常解析器,统一处理

九、拦截器

9.1 作用9.2 定义拦截器9.3 配置拦截路径

十、上传

10.1 导入jar10.2 表单10.3 上传解析器10.4 Handler

十一、下载

11.1 超链11.2 Handler

十二、验证码

12.1 作用12.2 导入jar12.3 声明验证码组件12.4 Page

十三、REST

13.1 开发风格13.2 优点13.3 使用13.3.1 定义Rest风格的 Controller13.3.2 Ajax请求

十四、跨域请求

14.1 域14.2 Ajax跨域问题14.3 解决方案

十五、SpringMVC执行流程

十六、Spring整合

16.1 整合思路16.2 整合技巧

一、SpringMVC

1.1 引言

java开源框架,Spring Framework的一个独立模块。

MVC框架,在项目中开辟MVC层次架构   

对控制器中的功能 包装 简化 扩展践行工厂模式,功能架构在工厂之上

1.2 MVC架构

1.2.1 概念

名称职责

Model模型:即业务模型,负责完成业务中的数据通信处理,对应项目中的 service和dao

View视图:渲染数据,生成页面。对应项目中的Jsp

Controller控制器:直接对接请求,控制MVC流程,调度模型,选择视图。对应项目中的Servlet

1.2.2 好处

MVC是现下软件开发中的最流行的代码结构形态;

人们根据负责的不同逻辑,将项目中的代码分成 M V C 3个层次;

层次内部职责单一,层次之间耦合度低;

符合低耦合 高内聚的设计理念。也实际有利于项目的长期维护。

二、开发流程

2.1 导入依赖

    

            org.springframework

            spring-webmvc

            5.1.6.RELEASE

    

2.2 配置核心(前端)控制器

作为一个MVC框架,首先要解决的是:如何能够收到请求!

所以MVC框架大都会设计一款前端控制器,选型在 Servlet 或 Filter两者之一,在框架最前沿率先工作,接收所有请求。

此控制器在接收到请求后,还会负责springMVC的核心的调度管理,所以既是前端又是核心。

    mvc

    org.springframework.web.servlet.DispatcherServlet

    

    

        contextConfigLocation

        classpath:mvc.xml

    

    

    1

    mvc

    /

2.3 后端控制器

等价于之前定义的Servlet

@Controller//声明这是一个控制器

@RequestMapping("/hello")//访问路径 ,等价于url-pattern

publicclassHelloController{

    @RequestMapping("/test1")//访问路径

    publicStringhello1(){

        System.out.println("hello world");

        return"index";// 跳转:/index.jsp  

    }

    @RequestMapping("/test2")//访问路径

    publicStringhello2(){

        System.out.println("hello c9");

        return"views/users";//  跳转:/views/user.jsp

    }

}

2.4 配置文件

默认名称:核心控制器名-servet.xml    默认位置:WEB-INF

随意名称:mvc.xml          随意位置:resources    但需要配置在核心控制器中

        xmlns:context="http://www.springframework.org/schema/context"

        xmlns:mvc="http://www.springframework.org/schema/mvc"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans

                            http://www.springframework.org/schema/beans/spring-beans.xsd

                            http://www.springframework.org/schema/context

                            http://www.springframework.org/schema/context/spring-context.xsd

                            http://www.springframework.org/schema/mvc

                            http://www.springframework.org/schema/mvc/spring-mvc.xsd">

   

   

   

   

   

   

       

       

       

       

   

2.5 访问

http://localhost:8989/hello/test1

http://localhost:8989/hello/test2

三、接收请求参数

3.1 基本类型参数

请求参数和方法的形参 同名即可

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")

publicStringtestParam1(Integerid,

Stringname,

Booleangender,

@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")Datebirth){

System.out.println("test param1");

return"index";

}

3.2 实体收参【重点】

请求参数和实体的属性 同名即可

publicclassUser{

    privateIntegerid;

    privateStringname;

    @DateTimeFormat(pattern="yyyy-MM-dd")

    privateDatebirth;

    privateBooleangender;

    //set/get ...

}

//http://localhost:8989/.../test2?id=1&name=zzz&gender=false&birth=2018-12-12 12:20:30

@RequestMapping("/test2")

publicStringtestParam2(Useruser){

System.out.println("test param2");

System.out.println("user:"+user);

return"index";

}

3.3 数组收参

简单类型的 数组

   ......

足球

篮球

排球


//http://localhost:8989/.../test3?hobby=football&hobby=basketball

@RequestMapping("/test3")

publicStringtestParam3(String[]hobby){

for(Stringh:hobby){

System.out.print(h+" ");

   }

return"index";

}

3.4 集合收参 【了解】

publicclassUserList{

    //private User[] users;

    privateListusers;

    //set/get..

}

//

// post请求:http://...?users[0].id=1&users[0].name=zhangsan&users[0].birth=2018-12-12&users[1].id=2&....

@RequestMapping("/test4")

publicStringtestParam4(UserListuserList){

for(Useruser:userList.getUsers()){

System.out.println(user);

   }

return"index";

}

3.5 路径参数

// {id} 定义名为id的路径;【/hello/{id}】的匹配能力和【/hello/*】等价

// http://localhost:8989/.../hello/10   {id}匹配到10

@RequestMapping("/hello/{id}")

// @PathVariable将{id}路径匹配到值赋给id参数

// 路径名和参数名相同则@PathVariable("id")可简写为 @PathVariable

publicStringtestParam5(@PathVariable("id")Integerid){

System.out.println("id:"+id);

return"index";

}

// http://localhost:8989/.../hello/tom   {username}匹配到tom

@RequestMapping("/hello/{username}")

publicStringtestParam6(@PathVariable("username")Stringname){//将{username}路径匹配到的值赋给name参数

System.out.println("username:"+name);

return"index";

}

3.6 中文乱码

首先,页面中字符集统一

        JSP : <%@pagepageEncoding="utf-8"%>

        HTML :

其次,tomcat中字符集设置,对get请求中,中文参数乱码有效

        Tomcat配置:URIEncoding=utf-8

最后,设置此filter,对post请求中,中文参数乱码有效

encoding

org.springframework.web.filter.CharacterEncodingFilter

encoding

utf-8

encoding

/*

四、跳转

4.1 转发

@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"; //绝对路径

    }

}

4.2 重定向

@RequestMapping("/redir")

classRedirectController{

@RequestMapping("/test1")

publicStringtestRedirect1(){

System.out.println("test redirect1");

//重定向到 /redir/test1

//return "redirect:test1"; //相对路径(转发到本类中的test1)

return"redirect:/redir/test1";//绝对路径

   }

@RequestMapping("/test2")

publicStringtestRedirect2(){

System.out.println("test redirect2");

//重定向到 /views/users.jsp

return"redirect:/view/user.jsp";

   }

}

4.3 跳转细节

    在增删改之后,为了防止请求重复提交,重定向跳转

    在查询之后,可以做转发跳转

五、传值

    C得到数据后,跳转到V,并向V传递数据。进而V中可以渲染数据,让用户看到含有数据的页面

    转发跳转:Request作用域

    重定向跳转:Session作用域

5.1 Request和Session

//形参中 即可获得 request 和 session对象

@RequestMapping("/test1")

publicStringtestData(HttpSessionsession,HttpServletRequestreq,Integerid){

session.setAttribute("user",newUser());

req.setAttribute("age",18);

req.setAttribute("users",Arrays.asList(newUser(),newUser()));

//return "test2";

return"forward:/WEB-INF/test2.jsp";

}

5.2 JSP中取值

建议:重点复习 EL  JSTL

    //jsp中用EL表达式 取值即可

    

    ${sessionScope.user.birth}

    ${requestScope.age}

5.3 Model

//model中的数据,会在V渲染之前,将数据复制一份给request

@RequestMapping("/test")

publicStringtestData(Modelmodel){

model.addAttribute("name","张三");

return"index";

}

//jsp中用EL表达式 取值即可

${requestScope.name}

5.4 ModelAndView

//modelandview 可以集中管理 跳转和数据

@RequestMapping("/test")

publicModelAndViewtestData(){//返回值类型为ModelAndView

//新建ModelAndView对象

ModelAndViewmv=newModelAndView();

// 设置视图名,即如何跳转

mv.setViewName("forward:/index.jsp");

// 增加数据

mv.addObject("age",18);

returnmv;

}

//jsp中用EL表达式 取值即可

${requestScope.age}

5.5 @SessionAttributes

@SessionAttributes({"gender","name"})  :model中的 name和gender 会存入session中

SessionStatus 移除session

@Controller

@SessionAttributes({"gender","name"})// model中的 name和gender 会存入session中

publicclassUserController{

@RequestMapping("/hello")

publicStringhello(Modelm){

m.addAttribute("gender",true);// 会存入session

mv.addObject("name","zhj");// 会存入session

return"index";

   }


@RequestMapping("/hello2")

publicStringhello(SessionStatusstatus){

// 移除通过SessionAttributes存入的session

status.setComplete();

return"index";

   }

}

六、静态资源

6.1 静态资源问题

静态资源:html,js文件,css文件,图片文件

静态文件没有url-pattern,所以默认是访问不到的,之所以可以访问,是因为,tomcat中有一个全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是 "/",是全局默认的Servlet.  所以每个项目中不能匹配的静态资源的请求,有这个Servlet来处理即可。

但,在SpringMVC中DispatcherServlet也采用了 “/” 作为url-pattern, 则项目中不会再使用全局的Serlvet,则静态资源不能完成访问。

6.2 解决方案1

DispathcerServlet采用其他的url-pattern

此时,所有访问handler的路径都要以 action结尾!!

    

          mvc9

          org.springframework.web.servlet.DispatcherServlet

    

    

        mvc9

        *.action

    

6.3 解决方案2

DispathcerServlet的url-pattern依然采用 "/",但追加配置

6.4 解决方案3

mapping是访问路径,location是静态资源存放的路径

将/html/** 中 /**匹配到的内容,拼接到 /hhh/后http://..../html/a.html  访问 /hhh/a.html

七、Json处理

7.1 导入依赖

    

        com.fasterxml.jackson.core

        jackson-databind

    2.9.8

7.2 使用@ResponseBody

@Controller

publicclassJsonController{

    @RequestMapping("/test1")

@ResponseBody//将handler的返回值,转换成json(jackson),并将json响应给客户端。

publicUserhello1(){

System.out.println("hello world");

Useruser=newUser();

returnuser;

   }

// @ResponseBody还可以用在handler的返回值上

@RequestMapping("/test2")

public@ResponseBodyListhello2(){

System.out.println("hello world");

Listusers=Arrays.asList(newUser(),newUser());

returnusers;

   }

// 如果返回值已经是字符串,则不需要转json,直接将字符串响应给客户端

@RequestMapping(value="/test3",produces="text/html;charset=utf-8")//produces 防止中文乱码

@ResponseBody

publicStringhello2(){

System.out.println("hello world");

return"你好";

   }

}

7.3 使用@RestController

Controller类上加了@RestController注解,等价于在类中的每个方法上都加了@ResponseBody

@Controller

@RestController

publicclassJsonController{

@RequestMapping("/test1")

publicUserhello1(){

System.out.println("hello world");

Useruser=newUser();

returnuser;

   }

//@ResponseBody还可以用在handler的返回值上

@RequestMapping("/test2")

publicListhello2(){

System.out.println("hello world");

Listusers=Arrays.asList(newUser(),newUser());

returnusers;

   }

}

7.4 使用@RequestBody

    @RequestBody, 接收Json参数

7.4.1 定义Handler

classUser{

privateIntegerid;

privateStringname;

privateBooleangender;

//set get

}

@RequestMapping("/users")

publicStringaddUser(@RequestBodyUseruser){//@RequestBody将请求体中的json数据转换为java对象

    System.out.println("cap2");

    System.out.println("Post user :"+user);

    return"index";

}

7.4.2 Ajax发送json

varxhr=newXMLHttpRequest();

xhr.open("post","${pageContext.request.contextPath}/users?"+newDate().getTime());

xhr.setRequestHeader("content-type","application/json");//设置请求头

xhr.send('{"id":1,"name":"shine","gender":"true"}');//传递json串

//ajax

varuser={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.log(ret);

   }

});

7.5 Jackson常用注解

7.5.1 日期格式化

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")

publicclassUser{

    privateIntegerid;

    privateStringname;

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

    privateDatebirth;

   ....

get/set

}

7.5.2 属性名修改

@JsonProperty("new_name")

publicclassUser{

    @JsonProperty("new_id")//不再使用原属性名,而是 "new_id"

privateIntegerid;

    privateStringname;

   ....

get/set

}

输出的json:{“new_id”:xx,"name":"xx"}

7.5.3 属性忽略

@JsonIgnore

publicclassUser{

privateIntegerid;

@JsonIgnore// 生成json时,忽略此属性

    privateStringname;

   ....

get/set

}

输出json时: {"id":xx}

7.5.4 null和empty属性排除

Jackson 默认会输出null值的属性,如果不需要,可以排除。

@JsonInclude(JsonInclude.Include.NON_NULL) //null值 属性不输出@JsonInclude(value= JsonInclude.Include.NON_EMPTY) // empty属性不输出( 空串,长度为0的集合,null值)

publicclassUser{

privateIntegerid;

@JsonInclude(JsonInclude.Include.NON_NULL)// 若"name==null" 忽略此属性

    privateStringname;

@JsonInclude(value=JsonInclude.Include.NON_EMPTY)// 若hobby长度为0或==null 忽略此属性

privateListhobby;

   ....

get/set

}

如果name=null,且hobby长度为0,则输出json时:{"id":xx}

7.5.5 自定义序列化

@JsonSerialize(using = MySerializer.class) // 使用MySerializer输出某属性

publicclassUser{

privateIntegerid;

privateStringname;

@JsonSerialize(using=MySerializer.class)

privateDoublesalary=10000.126;//在输出此属性时,使用MySerializer输出

   ....

get/set

}

则输出json时:{"id":xx,"name":"xxx","salary":10000.13}

publicclassMySerializerextendsJsonSerializer{

// value即 Double salary的值

@Override

publicvoidserialize(Doublevalue,JsonGeneratorgen,SerializerProviderserializers)throwsIOException{

// 将Double salary的值 四舍五入

Stringnumber=BigDecimal.valueOf(value).setScale(2,BigDecimal.ROUND_HALF_UP).toString();

// 输出 四舍五入后的值

gen.writeNumber(number);

   }

}

7.6 FastJson

7.6.1 导入依赖

    com.alibaba

    fastjson

    1.2.54

7.6.2 安装FastJson

    

    

    

         

                application/json

        

     

    

7.6.3 使用

@ResponseBody  @RequestBody @RestController 使用方法不变

7.6.4 常用注解

日期格式化:@JSONField(format="yyyy/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)

publicclassUserimplementsSerializable{

    @JSONField(serialize=false)

privateIntegerid;

@JSONField(name="NAME",serialzeFeatures=SerializerFeature.WriteNullStringAsEmpty)

    privateStringname;

@JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue)

privateStringcity;

    @JSONField(format="yyyy/MM/dd")

    privateDatebirth;

@JSONField(serializeUsing=MySerializer2.class)

privateDoublesalary;

    ...

}

publicclassMySerializer2implementsObjectSerializer{

@Override

publicvoidwrite(JSONSerializerserializer,Objectobject,ObjectfieldName,TypefieldType,

intfeatures)throwsIOException{

Doublevalue=(Double)object;// salary属性值

Stringtext=value+"元";// 在salary后拼接 “元”

serializer.write(text);// 输出拼接后的内容

   }

}

newUser(1,null,null,newDate(),100.5);

// 如上对象,转换json:

{NAME:"",city:null,"birth":"2020/12/12","salary":"100.5元"}

八、异常解析器

8.1 现有方案,分散处理

Controller中的每个Handler自己处理异常

此种处理方案,异常处理逻辑,分散在各个handler中,不利于集中管理

publicStringxxx(){

try{

    ...

}catch(Exception1e){

    e.printStackTrace();

return"redirect:/xx/error1";

}catch(Exception2e){

    e.printStackTrace();

return"redirect:/xx/error2";

   }

}

8.2 异常解析器,统一处理

Controller中的每个Handler不再自己处理异常,而是直接throws所有异常。

定义一个“异常解析器” 集中捕获处理 所有异常

此种方案,在集中管理异常方面,更有优势!

publicclassMyExResolverimplementsHandlerExceptionResolver{

    /**

    * 异常解析器:主体逻辑

    * 执行时刻:当handler中抛出异常时,会执行:捕获异常,并可以跳到错误页面

    */

    @Override

    publicModelAndViewresolveException(HttpServletRequestrequest,

            HttpServletResponseresponse,Objecthandler,Exceptionex) {

        ex.printStackTrace();//打印异常栈

        //创建一个ModelAndView

        ModelAndViewmv=newModelAndView();

        //识别异常

        if(exinstanceofException1) {

            mv.setViewName("redirect:/xxx/error1");

        }elseif(exinstanceofException2){

            mv.setViewName("redirect:/xxx/error2");

        }else{

            mv.setViewName("redirect:/xxx/error");

        }

        returnmv;

    }

}

   

九、拦截器

9.1 作用

作用:抽取handler中的冗余功能

9.2 定义拦截器

执行顺序: preHandle--postHandle--afterCompletion

publicclassMyInter1implementsHandlerInterceptor{

    //主要逻辑:在handler之前执行:抽取handler中的冗余代码

    @Override

    publicbooleanpreHandle(HttpServletRequestrequest,

            HttpServletResponseresponse,Objecthandler)throwsException{

        System.out.println("pre~~~");

/*

response.sendRedirect("/springMVC_day2/index.jsp");//响应

return false;//中断请求

*/

        returntrue;//放行,后续的拦截器或handler就会执行

    }

    //在handler之后执行:进一步的响应定制

    @Override

    publicvoidpostHandle(HttpServletRequestrequest,

            HttpServletResponseresponse,Objecthandler,

            ModelAndViewmodelAndView)throwsException{

        System.out.println("post~~");

    }

    //在页面渲染完毕之后,执行:资源回收

    @Override

    publicvoidafterCompletion(HttpServletRequestrequest,

            HttpServletResponseresponse,Objecthandler,Exceptionex)

            throwsException{

        System.out.println("after~~");

    }

}

9.3 配置拦截路径

十、上传

10.1 导入jar

    commons-io

    commons-io

    2.4

    commons-fileupload

    commons-fileupload

    1.3.3

    javax.servlet

    servlet-api

10.2 表单

    file:

    

10.3 上传解析器

10.4 Handler

@RequestMapping("/test1")

publicStringhello1(Stringusername,MultipartFilesource,HttpSessionsession) {

//文件的原始名称

Stringfilename=source.getOriginalFilename();

//定制全局唯一的命名

Stringunique=UUID.randomUUID().toString();

//获得文件的后缀

Stringext=FilenameUtils.getExtension(filename);//abc.txt   txt    hello.html  html

//定制全局唯一的文件名

StringuniqueFileName=unique+"."+ext;

System.out.println("唯一的文件名:"+uniqueFileName);

//文件的类型

Stringtype=source.getContentType();

System.out.println("filename:"+filename+" type:"+type);

//获得 upload_file的磁盘路径 ==> 在webapp目录下创建一个目录"upload_file",且此目录初始不要为空,否则编译时被忽略

Stringreal_path=session.getServletContext().getRealPath("/upload_file");

System.out.println("real_path:"+real_path);

//将上传的文件,存入磁盘路径中

//source.transferTo(new File("d:/xxxx/xxxx/xx.jpg"))

source.transferTo(newFile(real_path+"\\"+uniqueFileName));

return"index";

}

十一、下载

11.1 超链

下载

11.2 Handler

@RequestMapping("/test1")

publicvoidhello1(Stringname,HttpSessionsession,HttpServletResponseresponse){

System.out.println("name:"+name);

//获得要下载文件的绝对路径

Stringpath=session.getServletContext().getRealPath("/upload_file");

//文件的完整路径

Stringreal_path=path+"\\"+name;

//设置响应头  告知浏览器,要以附件的形式保存内容   filename=浏览器显示的下载文件名

response.setHeader("content-disposition","attachment;filename="+name);

//读取目标文件,写出给客户端

IOUtils.copy(newFileInputStream(real_path),response.getOutputStream());

//上一步,已经是响应了,所以此handler直接是void

}

十二、验证码

12.1 作用

防止暴力攻击,前端安全保障

12.2 导入jar

    com.github.penggle

    kaptcha

    2.3.2

    

        

                javax.servlet

                javax.servlet-api

        

    

12.3 声明验证码组件

    cap

    com.google.code.kaptcha.servlet.KaptchaServlet

    

        kaptcha.border

        no

    

    

        kaptcha.textproducer.char.length

        4

    

    

        kaptcha.textproducer.char.string

        abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

    

    

        kaptcha.background.clear.to

        211,229,237

    

    

    

        kaptcha.session.key

        captcha

    

        cap

        /captcha

12.4 Page

十三、REST

13.1 开发风格

是一种开发风格,遵从此风格开发软件,符合REST风格,则RESTFUL。

两个核心要求:

每个资源都有唯一的标识(URL)

不同的行为,使用对应的http-method

访问标识资源

http://localhost:8989/xxx/users所有用户

http://localhost:8989/xxx/users/1用户1

http://localhost:8989/xxx/users/1/orders用户1的所有订单

请求方式标识意图

GEThttp://localhost:8989/xxx/users查询所有用户

POSThttp://localhost:8989/xxx/users在所有用户中增加一个

PUThttp://localhost:8989/xxx/users在所有用户中修改一个

DELETEhttp://localhost:8989/xxx/users/1删除用户1

GEThttp://localhost:8989/xxx/users/1查询用户1

GEThttp://localhost:8989/xxx/users/1/orders查询用户1的所有订单

POSThttp://localhost:8989/xxx/users/1/orders在用户1的所有订单中增加一个

13.2 优点

**输出json:

13.3 使用

13.3.1 定义Rest风格的 Controller

@RequestMapping(value="/users",method = RequestMethod.GET)

等价

@GetMapping("/users")

@RestController

publicclassRestController{

@GetMapping("/users")

publicListqueryAllUsers(){

    System.out.println("get");

    Listusers=....

    return users;

   }

@PostMapping("/users")

publicStringaddUser(@RequestBodyUseruser){

System.out.println("Post user :"+user);

return "{status:1}";

   }


@PutMapping("/users")

publicStringupdateUser(@RequestBodyUseruser){

    System.out.println("Put user"user:"+user);

    return "{status:1}";

   }

@GetMapping("/users/{id}")

publicStringqueryOneUser(@PathVariableIntegerid){//@PathVariable 接收路径中的值

    System.out.println("Get user id:"+id);

    return "{status:1}";

   }

@DeleteMapping("/users/{id}")

publicStringdeleteOneUser(@PathVariableIntegerid){//@PathVariable 接收路径中的值

    System.out.println("delete user id:"+id);

    return"{status:1}";

   }

}

13.3.2 Ajax请求

十四、跨域请求

14.1 域

域:协议+IP+端口

http://localhost:8989

http://localhost:8080

http://www.baidu.com:80

14.2 Ajax跨域问题

Ajax发送请求时,不允许跨域,以防用户信息泄露。

当Ajax跨域请求时,响应会被浏览器拦截(同源策略),并报错。即浏览器默认不允许ajax跨域得到响应内容。

互相信任的域之间如果需要ajax访问,(比如前后端分离项目中,前端项目和后端项目之间),则需要额外的设置才可正常请求。

14.3 解决方案

允许其他域访问

在被访问方的Controller类上,添加注解

@CrossOrigin("http://localhost:8080")//允许此域发请求访问

publicclassSysUserController{

    ....

}

携带对方cookie,使得session可用

在访问方,ajax中添加属性:withCredentials: true

$.ajax({

type:"POST",

url:"http://localhost:8989/web/sys/login",

...,

xhrFields: {

// 跨域携带cookie

withCredentials:true

    }

});

varxhr=newXMLHttpRequest();

// 跨域携带cookie

xhr.withCredentials=true;

十五、SpringMVC执行流程


十六、Spring整合

16.1 整合思路

此时项目中有两个工厂

DispatcherServlet 启动的springMVC工厂==负责生产C及springMVC自己的系统组件

ContextLoaderListener 启动的spring工厂==负责生产其他所有组件

springMVC的工厂会被设置为spring工厂的子工厂,可以随意获取spring工厂中的组件

整合过程,就是累加:代码+依赖+配置。然后将service注入给controller即可

16.2 整合技巧

两个工厂不能有彼此侵入,即,生产的组件不能有重合。

 

   

你可能感兴趣的:(springmvc)