RESTful架构
REST全名为:Representational State Transfer。资源表现层状态转化。是目前最流行的一种互联网软件架构。
它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
资源(Resources)
网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。
表现层(Representation)
把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
状态转化(State Transfer)
每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。
特点:
1.url更加简洁,将参数通过url传到服务端。
普通的url:地址栏/queryUserById?id=1
REST的url风格:地址栏/queryUserById/1
2.有利于不同系统之间的资源共享,只需要遵守规范,不需要做其他的配置就能达到资源共享。
Restful具体来讲就是四种表现形式,分别对应四种基本操作:
GET:用来获取资源,
POST:用来新建资源,
PUT:用来修改资源,
DELETE:用来删除资源。
但是,form表单只支持 GET与 POST 请求,不支持DELETE、PUT,因此可以使用ajax的方式
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> <script type="text/javascript"> $(function(){ $("#get").click(function(){ var id = $("#get_id").val(); $.ajax({ url:"httpGet/"+id, type:"get", dataType:"json", success:function(data){ if(data == null){ alert("该用户不存在"); }else{ alert(data.id+"---"+data.name+"---"+data.age); } } }) }); $("#post").click(function(){ var id = $("#post_id").val(); var name = $("#post_name").val(); var age = $("#post_age").val(); $.ajax({ url:"httpPost/"+id+"/"+name+"/"+age, type:"post", dataType:"json", success:function(data){ alert(data.id+"---"+data.name+"---"+data.age); } }) }); $("#put").click(function(){ var id = $("#put_id").val(); var name = $("#put_name").val(); var age = $("#put_age").val(); $.ajax({ url:"httpPut/"+id+"/"+name+"/"+age, type:"put", dataType:"json", success:function(data){ alert(data.id+"---"+data.name+"---"+data.age); } }) }); $("#delete").click(function(){ var id = $("#delete_id").val(); $.ajax({ url:"httpDelete/"+id, type:"delete", dataType:"text", success:function(data){ alert(data); } }) }); }) </script>
Java层的代码
@Controller public class RestfulHandler { private static Map<Integer,Student> students; static{ students = new HashMap<Integer,Student>(); students.put(1, new Student(1,"zhangsan",22)); } @RequestMapping(value="/httpGet/{id}",method=RequestMethod.GET) @ResponseBody public Student httpGet(@PathVariable(value="id")int id){ return students.get(id); } @RequestMapping(value="/httpPost/{id}/{name}/{age}",method=RequestMethod.POST) @ResponseBody public Student httpPost(@PathVariable(value="id")int id,@PathVariable(value="name")String name,@PathVariable(value="age")int age){ Student student = new Student(id,name,age); students.put(student.getId(), student); return student; } @RequestMapping(value="/httpDelete/{id}",method=RequestMethod.DELETE) @ResponseBody public String httpDelete(@PathVariable(value="id")int id){ students.remove(id); return "delete-ok"; } @RequestMapping(value="/httpPut/{id}/{name}/{age}",method=RequestMethod.PUT) @ResponseBody public Student httpPut(@PathVariable(value="id")int id,@PathVariable(value="name")String name,@PathVariable(value="age")int age){ Student student = new Student(id,name,age); students.put(student.getId(), student); return student; } }
注意:后台返回json数据需要修改xml文件,增加Jackson的包。
文件上传/下载
Web项目中,文件上传功能几乎是必不可少的,实现的技术有很多,甚至在WEB层以及有封装好的。
单文件上传
1.底层还是Apache fileupload组件完成上传,SpringMVC只是进行了封装,需要引入fileupload的包。
2.springmvc.xml配置CommonsMultipartResolver。
<!-- id必须是multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 处理文件名中文乱码 --> <property name="defaultEncoding" value="utf-8"/> <!-- 设置多文件上传,总大小上限,不设置默认没有限制,单位为字节,1M=1*1024*1024 --> <property name="maxUploadSize" value="1048576"/> <!-- 设置每个上传文件的大小上限 --> <property name="maxUploadSizePerFile" value="1048576"/> </bean>
3.JSP页面的input的type设置为file。form表单的method设置为post,并且enctype设置为multipart/form-data。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="img"> <input type="submit" name="提交"> </form><br /> <c:if test="${filePath!=null }"> <h1>上传的图片</h1><br /> <img width="300px" src="<%=basePath %>${filePath}"/> </c:if> </body> </html>
4.Java方法,使用MultipartFile对象作为参数,接收前端发送过来的文件,并完成上传操作。
@RequestMapping(value="/upload", method = RequestMethod.POST) public String upload(@RequestParam(value="img")MultipartFile img, HttpServletRequest request) throws Exception { //getSize()方法获取文件的大小来判断是否有上传文件 if (img.getSize() > 0) { //获取保存上传文件的file文件夹绝对路径 String path = request.getSession().getServletContext().getRealPath("file"); //获取上传文件名 String fileName = img.getOriginalFilename(); File file = new File(path, fileName); img.transferTo(file); //保存上传之后的文件路径 request.setAttribute("filePath", "file/"+fileName); return "upload"; } return "error"; }
多文件上传
//和单文件上传类似,input的name属性要一致,接收的参数需要是数组类型 @RequestMapping(value="/uploads", method = RequestMethod.POST) public String uploads(@RequestParam MultipartFile[] imgs, HttpServletRequest request) throws Exception { //创建集合,保存上传后的文件路径 List<String> filePaths = new ArrayList<String>(); for (MultipartFile img : imgs) { if (img.getSize() > 0) { String path = request.getSession().getServletContext().getRealPath("file"); String fileName = img.getOriginalFilename(); File file = new File(path, fileName); filePaths.add("file/"+fileName); img.transferTo(file); } } request.setAttribute("filePaths", filePaths); return "uploads"; }
文件下载
1.在JSP使用超链接的方式进行文件下载,也可以使用按钮方式。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="download?fileName=aaa.jpg">下载图片</a> </body> </html>
2.JAVA方法。
@RequestMapping("/download") public void downloadFile(String fileName,HttpServletRequest request, HttpServletResponse response){ if(fileName!=null){ //获取file绝对路径 String realPath = request.getServletContext().getRealPath("file/"); File file = new File(realPath,fileName); OutputStream out = null; if(file.exists()){ //设置下载类型,具体百度 response.setContentType("application/force-download"); //设置文件名 response.setHeader("Content-Disposition", "attachment;filename="+fileName); try { out = response.getOutputStream(); //写入前台页面 out.write(FileUtils.readFileToByteArray(file)); out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(out != null){ try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }