一,SpringMVC的常用注解
一,RequestMaping
作用:为类和方法提供映射关系
源码:
//ElementType.METHOD作用于方法,ElementType.TYPE作用于类 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)//运行级别 @Documented//它代表着此注解会被javadoc工具提取成文档 @Mapping public @interface RequestMapping { String name() default ""; //path和value作用是一样的,声明映射路径 @AliasFor("path") String[] value() default {}; @AliasFor("value") String[] path() default {}; //声明请求类型枚举数组类型 RequestMethod[] method() default {}; //声明映射参数 String[] params() default {}; //声明请求头部信息 String[] headers() default {}; //声明数据请求提交的类型 String[] consumes() default {}; //声明数据请求返回的数据类型 String[] produces() default {}; }
一,RequestMapping的属性:
1,path和value
说明资源映射的路径
2,RequestMethod
说明请求的类型它是一个枚举类,总共有八种请求方式
public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; private RequestMethod() { }
3,param
说明请求头需要声明的参数,匹配则请求成功,反之失败
4,headers
说明请求需要的请求头部信息,匹配则请求成功,反之失败
5,consumes和produces
声明请求和响应的数据类型
数据类型:
常见的媒体格式类型如下:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
以application开头的媒体格式类型:
- application/xhtml+xml :XHTML格式
- application/xml : XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json : JSON数据格式
- application/pdf :pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
二,RequestMapping请求参数的绑定
绑定参数名或者提供的input的name必须要和方法的参数名保持一致,这样才能形成映射关系
一,get请求的绑定
标签:
<a href="/wql?name=10" >a</a>
类:
@Controller public class test1 { @RequestMapping(path = "/wql") public void enter(String name){//a标签的参数name和方法的形参形成对应关系 System.out.println(name); } }
输出结果:10
二,post请求绑定
标签:
<form action="${pageContext.request.contextPath}/wql"> 账号:<input type="text" name="account"> 密码:<input type="text" name="password"> <input type="submit" value="提交"> </form>
类:
@Controller public class test1 { @RequestMapping(path = "/wql") public void enter(String account,String password){ System.out.println(account+"\n"+password); } }
三,绑定bean对象
bean对象类:
@Controller public class WQL1 { String account; String password; public String getAccount() { return account; } public String getPassword() { return password; } public void setAccount(String account) { this.account = account; } public void setPassword(String password) { this.password = password; } }
标签:
<form action="${pageContext.request.contextPath}/wql"> <%--名称和bean实体类中的属性名一致--%> 账号:<input type="text" name="account"> 密码:<input type="text" name="password"> <input type="submit" value="提交"> </form>
RequestMapping:
@Controller public class test1 { @RequestMapping(path = "/wql") public void enter(WQL1 wql1){//提交的数据和bean对象的属性自动产生映射 System.out.println(wql1.account+"\n"+wql1.password); } }
三,绑定集合
实体类:
Controller public class WQL1 { String account; String password; ArrayList<String> list; Map<String,String> map; public ArrayList<String> getList() { return list; } public void setList(ArrayList<String> list) { this.list = list; } public Map<String, String> getMap() { return map; } }
表单:
<form action="${pageContext.request.contextPath}/wql"> 账号:<input type="text" name="account"> 密码:<input type="text" name="password"> name:<input type="text" name="list[0]"> map:<input type="text" name="map['age']"> <input type="submit" value="提交"> </form>
Requestmapping:
@Controller public class test1 { @RequestMapping(path = "/wql") public void enter(WQL1 wql1){ System.out.println(wql1.account+"\n"+wql1.password+"\n"+ wql1.list.get(0)+"\n"+wql1.map.get("age")); } }
二,RequestParam
作用:用于获取传入参数的值,之前获取参数的值形参的名称必须要和表单的名称一致,通过RequestParam名称不需要一致
源码:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam { //name和value一样,输入映射的名称,必须要和表单的名称一致 @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; //参数是否必须 boolean required() default true; String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"; }
属性:
- name和value:输入映射的名称,必须和表单的name一致
-
required:是否参数必须
例:
<form action="/wql1"> <input type="text" name="name" > <input type="submit" value="提交"> </form>
@Controller public class test2 { @RequestMapping(path = "/wql1") public void wql(@RequestParam(value = "name") String a){ System.out.print(a); }
三,RequestHeader和CookieValue
RequestHeader:获取请求头部信息
CookieValue:获取Cookie信息
RequestHeader源码:
public @interface RequestHeader { //name和value声明请求头的key @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; //是否必须要请求头部信息 boolean required() default true; String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"; }
CookieValue源码:
public @interface CookieValue { //name和value声明Cookie的key @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; //是否必须要Cookie信息 boolean required() default true; String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"; }
例:
@Controller public class test2 { @RequestMapping(path = "/wql1") //把头部user-agent的值赋值给a变量,Cookie的JSESSIONID赋值给变量b public void wql(@RequestHeader(value = "user-agent") String a,@CookieValue(value ="JSESSIONID")String b){ System.out.print(a+"\n"+b);} }
四,PathVariable
PathVariable作用:用于绑定url占位符 例:/wql/{id} id获取任意的字符,通过@PathVariabl(name="id") String a 赋值给字符串a
PathVariable是SpringMVC支持Rest风格URL的重要标志
PathVariable源码:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface PathVariable { //name和value声明匹配的占位符ID @AliasFor("name") String value() default ""; @AliasFor("value") String name() default ""; //是否必须要占位符 boolean required() default true; }
例:
@Controller public class test3 { @RequestMapping(value = "/ww/{id}") public void c(@PathVariable(value = "id")String a){ System.out.print(a); } }
五,RequestBoby和ResponseBody
RequestBody:将表单数据作为一个整体转换为json数据,赋值给变量
ResponseBody:将对象类型数据和其他数据类型转换为json类型进行返回响应
RequestBody源码:
@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestBody { boolean required() default true;//唯一一个参数,是否必须要进行json数据获取 }
ResponseBody源码:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ResponseBody { }//无属性
例:
<form action="/wql2" method="post"> <input type="text" name="name" > <input type="text" name="password" > <input type="submit" value="提交"> </form>
public class test4 { @RequestMapping(value = "/wql2") public void aas(@RequestBody String body){ System.out.print(body); }
结果: name=wql&password=123456
二,SpringMVC中使用域对象
在SpringMVC中使用域对象有四种方式:
- 使用原生Servlet对象
- 使用ModelandView对象
- 使用Map集合
- Mode1对象
一,SpringMVC获取Servlet原生API
在SpringMVC中Hander方法形参中可以接收的Servlet类型的参数:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Locale
- InputStream
- OutputStream
- writer
- Reader
可以使用原生的HttpSession和HttpServletRequest获取域对象
例:
@RequestMapping(path = "/wql1") public String wql(HttpSession session, HttpServletRequest request){ session.setAttribute("name","wql"); request.setAttribute("age","10"); return "seccion"; } }
jsp:
<html> <head> <title>Title</title> </head> <body> <h1>${sessionScope.get("name")}</h1> <h2>${requestScope.get("age")}</h2> </body> </html>
二,ModelandView
ModelandView:Model设置域,View设置视图
构造ModelAndView对象当控制器处理完请求时,通常会将包含视图名称或视图对象以及一些模型属性的ModelAndView对象返回到DispatcherServlet。
因此,经常需要在控制器中构造ModelAndView对象。
ModelAndView类提供了几个重载的构造器和一些方便的方法,让你可以根据自己的喜好来构造ModelAndView对象。这些构造器和方法以类似的方式支持视图名称和视图对象。
通过ModelAndView构造方法可以指定返回的页面名称,也可以通过setViewName()方法跳转到指定的页面 , 使用addObject()设置需要返回的值,addObject()有几个不同参数的方法,可以默认和指定返回对象的名字。
构造方法:
ModelAndView() //默认构造函数豆式的用法:填充bean的属性,而不是将在构造函数中的参数。 ModelAndView(String viewName) //方便的构造时,有没有模型数据暴露。 ModelAndView(String viewName, Map model) //给出创建一个视图名称和模型新的ModelAndView。 ModelAndView(String viewName, String modelName, Object modelObject) //方便的构造采取单一的模式对象。 ModelAndView(View view) //构造方便在没有模型数据暴露。 ModelAndView(View view, Map model) //创建给定一个视图对象和模型,新的ModelAndView。 ModelAndView(View view, String modelName, Object modelObject) //方便的构造采取单一的模式对象。
类方法:
ModelAndView addAllObjects(Map modelMap) //添加包含在所提供的地图模型中的所有条目。 ModelAndView addObject(Object modelObject) //添加对象使用的参数名称生成模型。 ModelAndView addObject(String modelName,ObjectmodelObject) //对象添加到模型中。 void clear() //清除此ModelAndView对象的状态。 Map getModel() //返回的模型图。 protectedMap getModelInternal() //返回的模型图。 ModelMap getModelMap() //返回底层ModelMap实例(从不为null)。 View getView() //返回View对象,或者为null,如果我们使用的视图名称由通过一个ViewResolverDispatcherServlet会得到解决。 String getViewName() //返回视图名称由DispatcherServlet的解决,通过一个ViewResolver,或空,如果我们使用的视图对象。 boolean hasView() //指示此与否的ModelAndView有一个观点,无论是作为一个视图名称或作为直接查看实例。 boolean isEmpty() //返回此ModelAndView对象是否为空,即是否不持有任何意见,不包含模型。 boolean isReference() //返回,我们是否使用视图的参考,i.e. void setView(Viewview) //设置此ModelAndView的视图对象。 void setViewName(StringviewName) //此ModelAndView的设置视图名称,由通过一个ViewResolverDispatcherServlet会得到解决。 String toString() //返回这个模型和视图的诊断信息。 boolean wasCleared()?? //返回此ModelAndView对象是否为空的调用的结果,以清除(),即是否不持有任何意见,不包含模型。
例:
@Controller public class test2 { @RequestMapping(path = "/wql1") //使用ModelandView需要将ModelandView对象返回 public ModelAndView wql(){ ModelAndView a=new ModelAndView(); a.addObject("name","LOVE"); a.setViewName("seccion"); return a; } }
jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h2>${name}</h2> </body> </html>
结果:ModelandView页面的跳转是服务器内部的转发,url地址并不会发生改变
三,Mode1
源码:
public interface Model { //添加域 Model addAttribute(String var1, Object var2); Model addAttribute(Object var1); //将K-V存储在集合中进行存储 Model addAllAttributes(Collection<?> var1); Model addAllAttributes(Map<String, ?> var1); Model mergeAttributes(Map<String, ?> var1); boolean containsAttribute(String var1); Map<String, Object> asMap(); }
四,普通的Map集合
在形参中加入普通的Map集合,底层会把Map集合转化为ModleandView中的ModelMap集合
三,文件的上传
文件的上传的jar包:文件上传依赖包
- commons-fileupload
- commons-io
一,Servlet的传统文件上传
不多说
@Controller public class test8 { @RequestMapping(value = "/FQlove") public String addddd(HttpServletRequest request) throws Exception { //上传位置 String path = request.getServletContext().getRealPath("/wqlfq"); File file = new File(path); if(!file.exists()){ file.mkdir(); } //获取request的上传文件项 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload =new ServletFileUpload(diskFileItemFactory); //解析request List<FileItem> item=servletFileUpload.parseRequest(request); //遍历 for(FileItem item1 : item){ //判断当前FileItem是否是上传文件项 if(item1.isFormField()){ //它为true说明是普通表单项 }else { //上传文件项 String name = item1.getName(); System.out.print(name); item1.write(new File(path,name)); } } System.out.print("文件上传!!!"); return "seccion"; } }
二,SpringMVC实现文件的上传
SpringMVC的文件上传依赖于MultipartFile的类,它把上传的File文件封装成了MultipartFile类对象,通过操作MultipartFile实现文件的上传
底层原理:
MultipartFile源码:
public interface MultipartFile extends InputStreamSource { //获取请求url名称 String getName(); //获取上传文件的名称 String getOriginalFilename(); //获取文件的类型 String getContentType(); //判断是否为空 boolean isEmpty(); //获取文件大小 long getSize(); //缓冲数组 byte[] getBytes() throws IOException; //获取InputStream文件输入流 InputStream getInputStream() throws IOException; //直接对象上传文件进行复制的方法 void transferTo(File var1) throws IOException, IllegalStateException; }
一,环境准备
1,将依赖包放入web下的lib目录中
2,在SpringMVC中配置multipartResolver
<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--上传文件的最大大小,单位为字节 --> <property name="maxUploadSize" value="17367648787"/> <!-- 上传文件的编码 --> <property name="defaultEncoding" value="UTF-8"/> </bean>
二,SpringMVC文件上传(1)
jsp表单:inpu的type必须为file
<form action="/fs1" method="post" enctype="multipart/form-data"> 选择上传文件:<input type="file" name="upload"> <input type="submit" value="上传"> </form>
上传代码:
@Controller public class fs1 { @RequestMapping("/fs1") public String va(MultipartFile upload, HttpServletRequest request) throws IOException { //在项目路径下,创建文件夹 System.out.println("方式1!!!"); String path = request.getServletContext().getRealPath("fs1"); String name = upload.getOriginalFilename();//获取上传的文件名 //判断文件是否存在,不存在创建 File file = new File(path); if(!file.exists()){ file.mkdir(); } //获取上传的文件输入流 InputStream inputStream = upload.getInputStream(); //获取文件的输出流 OutputStream outputStream = new FileOutputStream(new File(file,name)); //文件的复制 int a=0; byte[] bytes = new byte[1024]; while ((a=inputStream.read(bytes))!=-1){ outputStream.write(bytes,0,a); } inputStream.close(); outputStream.close(); return "seccion"; } }
文件的上传目录:为当前项目目录下
三,SpringMVC文件上传(2)
@RequestMapping(value = "/we",method = RequestMethod.POST) public String vc(@RequestParam(value = "upload") MultipartFile upload, HttpServletRequest request) throws IOException { String path = request.getServletContext().getRealPath("photo"); System.out.println(path); File file = new File(path); if(!file.exists()){ file.mkdir(); } //方法直接打印 upload.transferTo(new File(file,upload.getOriginalFilename())); return "seccion"; }
四,restful风格
概述:
RESTful
也称之为REST(Representational State Transfer),可以理解为一种软件架构风格或者是设计风格
简单来说,RESTful风格就是把请求参数变成请求路径的一种风格
举个例子
而采用RESTful风格后,URL地址请求就会变成
注意:在ajax中它可以发生8中不同的请求,可以对应RequestMapping的值,当不使用ajax请求,普通的from表单只能发送两种请求(post,get),并不能发送请求类型请求,我们就需要一个类型转化的拦截器,进行中间的转化拦截,实现不同请求的rest风格实现
一,普通表单提交实现Restful风格
普通表单只能发送两种请求,我们需要在中间做类型的转化拦截器,把请求拦截(HiddenHttpMethodFilter)进行类型转化
HiddenHttpMethodFilter类型转换拦截器源码:
ublic class HiddenHttpMethodFilter extends OncePerRequestFilter { public static final String DEFAULT_METHOD_PARAM = "_method"; //1,通过这个固定name为键,所以表单所有put和delete是需要讲name设置为_method,值为具体的请求类型 private String methodParam = "_method"; public HiddenHttpMethodFilter() { } public void setMethodParam(String methodParam) { Assert.hasText(methodParam, "'methodParam' must not be empty"); this.methodParam = methodParam; } //3, protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest requestToUse = request; //判断表单类型是否为post类型,为post就执行,假如为get就直接跳过不就行转化 if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) { //接收input name参数的值 String paramValue = request.getParameter(this.methodParam); if (StringUtils.hasLength(paramValue)) { //讲值赋值给请求,就行请求类型转换 requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, paramValue); } } filterChain.doFilter((ServletRequest)requestToUse, response); } private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper { private final String method; //2,获取参数name为method的值 public HttpMethodRequestWrapper(HttpServletRequest request, String method) { super(request); //转化成大写 this.method = method.toUpperCase(Locale.ENGLISH); } //将大小后的method返回 public String getMethod() { return this.method; } } }
在web.xml中配置HiddenHttpMethodFilter:
<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>
例:使用put请求
<form> <!--必须在name中指定_method,值为请求类型,底层提供参数来获取类型--> <input type="hidden" name="_method" value="put"> <input type="submit" value="提交put请求"> </form>
代码:
@Controller public class tt { @RequestMapping(value = "/wq",method = RequestMethod.PUT ) public String f(HttpServletRequest request){ //获取请求类型 System.out.println(request.getMethod()); return "seccion"; } }
一,Ajax实现Restful风格
使用Ajax就不需要中间的拦截器了,业务Ajax可以提交多种不同类型的请求
//使用RESTful风格 @RequestMapping("/user/{id}") @ResponseBody public User selectUser(@PathVariable("id") String id){ //查看数据的接收 System.out.println("id->"+id); User user = new User(); //模拟根据id查询出到用户对象数据 if (id.equals("1234"))user.setUserName("tom"); return user; }
jsp: <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>RESTful测试</title> <script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script> <script type="text/javascript"> function search() { //获取输入的查询编号 var id = $("#number").val(); $.ajax({ url:"${pageContext.request.contextPath}/users/user/"+id, type:"GET", //定义回调响应的数据格式为JSON字符串 dataType:"JSON", success:function (data) { if (data.userName != null) { alert("您查询的用户:"+data.userName); }else { alert("没有查找到id为:"+id+"的用户") } } }); } </script> </head> <body> <form> 编号: <input type="text" name="number" id="number"> <input type="button" value="确定" onclick="search()"> </form> </body> </html
五,拦截器
一,拦截器和过滤器的区别
过滤器是Servlet配置的,它直接作用在Servlet上,拦截器是SpringMVC提供的在请求交由dispatcherServlet控制
过滤器的优先级高于拦截器
二,拦截器的实现方式
自定义拦截器主要有两种实现方式:
- 实现HandlerInterceptor接口
- 继承HandlerInterceptorAdapter适配器类
HandlerInterceptorAdapter和HandlerInterceptor的关系:HandlerInterceptorAdapter实现了HandlerInterceptor类,并对HandlerInterceptor接口方法进行了初始化
拦截器的三个主要方法:
1,preHandle():这个方法在handler处理器处理请求之前被调用,它的返回值为Boolean当拦截请求之后需要处理器去处理就返回true,不需要就返回false
2,postHandle():这个方法在处理器处理为请求逻辑之后,但DispatcherServlet控制器并没有返回结果时调用
3,afterCompletion():在DispatcherServlet完成处理好请求后被调用
三,拦截器的配置
拦截器在SpringMVC的配置文件中配置
1,方式1
<mvc:interceptors> <!--拦截的class,默认路径tt类下的所有请求--> <bean class="com.fq.tt"></bean> </mvc:interceptors>
2,方式2
<mvc:interceptors> <!--这种方式拦截器上必须加注解@Component--> <ref bean="tt"></ref> </mvc:interceptors>
3,方式3
<mvc:interceptors> <mvc:interceptor> <!--拦截的类--> <bean></bean> <!--类下要拦截的请求,默认全部请求--> <mvc:mapping path="/"/> <!--要放行的请求--> <mvc:exclude-mapping path=""/> </mvc:interceptor> </mvc:interceptors>
Comments | NOTHING
Warning: Undefined variable $return_smiles in /www/wwwroot/wql_luoqin_ltd/wp-content/themes/Sakura/functions.php on line 1109