力提升-生成圖形驗證碼
<!--訪問靜態資源和訪問控制器的結果都是一樣的---一個是靜態訪問圖片路徑------另一個是動態獲取圖片流 -->
(一)動態獲取圖片兩種方法:
1.靜態HTML獲取圖片地址(通過JSP腳本動態更換圖片路徑地址)
2.動態控制器Servlet(Java的I/O流控制輸出)
步驟一、
編寫JSP靜態獲取圖片地址頁面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path=request.getContextPath();String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <img alt="" src="/SecurityCode(安全碼)/WebRoot/images/ea111ec9e85c9a06f7756b488bfaae60.jpg"> </body></html>
瀏覽器輸出:
第二、通過Servlet控制器輸出I/O流文件的形式
package com.wq.Servlet;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/demo")public class DemoSrtvlet extends HttpServlet{ /** * */ private static final long serialVersionUID=1L; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 輸出文字流(獲取文字) //PrintWriter outPrintWriter=resp.getWriter(); //獲取響應流(圖片,視頻,文件等字節流) ServletOutputStream os=resp.getOutputStream(); //IO流獲取文件,getRealPath(arg0)獲取文件具體路徑;;File(getServletContext().getRealPath(""),"ea111ec9e85c9a06f7756b488bfaae60.jpg"));//文件路徑+文件名 InputStream iStream=new FileInputStream(new File(getServletContext().getRealPath("images"),"ea111ec9e85c9a06f7756b488bfaae60.jpg")); //輸入流轉輸出流(JavaSE I/O的時候必須會寫的代碼) int index=-1; while((index=iStream.read())!=-1){ //index讀取文件流直到等于-1 os.write(index); //同時寫入到http中--os.write(index); } }}
瀏覽器輸出:文件的形式
JSP獲取src路徑文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path=request.getContextPath();String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <img alt="" src="demo"><!--直接返回一個Servlet的圖片流 --> <!--訪問靜態資源和訪問控制器的結果都是一樣的---一個是靜態訪問圖片路徑------另一個是動態獲取圖片流 --> </body></html>
瀏覽器輸出;(效果一樣)
實現步驟
一、實現原理
public class BufferedImage
extends Image
implements WritableRenderedImage, Transparency所述BufferedImage亞類描述了一種Image與圖像數據的訪問的緩沖器。 A BufferedImage由圖像數據的ColorModel和Raster組成。 SampleModel中SampleModel中的Raster的數量和類型必須與ColorModel所要求的數字和類型相匹配,以表示其顏色和Alpha組件。 所有BufferedImage對象的左上角坐標為(0,0)。 Raster用于構建BufferedImage的任何BufferedImage必須具有minX=0和minY=0。
這個類依賴的數據獲取和設置方法Raster ,并在顏色表征方法ColorModel 。
JavaWeb Jquery Ajax實現驗證碼局部刷新和校驗
一:設置JSP頁面
(1):給form表單中的 "登錄" 按鈕設置onsubmit驗證點擊后調用checkCode()返回結果為true頁面跳轉,為false頁面不跳轉。
(2):通過標簽設置當點擊"看不清?"時調用flushImage();進 行驗局部證碼刷新。
(3):點擊注冊按鈕轉發到"register.jsp"頁面。
<body><form action="login.do" method="post" onsubmit="return checkCode()"> <h1>登錄頁面</h1> 用戶名:<input type="text" name="username"> </br></br> 密碼:<input type="password" name="password"> </br></br> 驗證碼:<input type="text" id="txt_code" name="code" size="5"> <img alt="驗證碼" id="code" src="image.do"> <a href="javascript:flushInamge();">看不清?</a> <span id="s_code"></span> </br></br> <input type="submit" value="登錄"> <a href="register.jsp"><input type="button" value="注冊"></a>
二:制作驗證碼
(1)制作java驗證碼并把產生的驗證碼字符串存儲在
(2)request.getSession().setAttribute("code", str);存儲在session中。
(3)利用ImageIO.write(image, "png", out);把圖片返回給ajax的回調函數。
else if("/image.do".equals(path)) {//生成驗證碼 //避免瀏覽器緩存 response.addHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //1.動態的創建一個圖片 //第一個參數高度 第二個參數高度 第三個參數圖片類型RGB BufferedImage image=new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB); //2.在圖片上畫字符 Graphics graphics=image.getGraphics(); graphics.setColor(Color.white);//改變圖片背景色默認黑色 graphics.fillRect(0, 0, 100, 30);//畫矩形 String str=""; Random rand=new Random(); Font font=new Font(null,Font.BOLD,20); for (int i=0; i < 5; i++) { int index=rand.nextInt(chars.length); Color color=new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255)); //生成一個隨機顏色字符 graphics.setColor(color); graphics.setFont(font); graphics.drawString(chars[index]+"", 30+i*10, 20); str+=chars[index]; } for (int i=0; i < 4; i++) { Color color=new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255)); graphics.setColor(color); graphics.drawLine(rand.nextInt(100), rand.nextInt(30), rand.nextInt(100), rand.nextInt(30)); } //3.將圖片上的文字保存到session中 request.getSession().setAttribute("code", str); //將圖片利用response輸出 OutputStream out=response.getOutputStream(); ImageIO.write(image, "png", out); }
三:創建jquery ajax請求通過Java進行校驗
(1):flushImamge();通過選擇器選擇名字為"code"的對象,發送image.do請求調用Java程序對'"code"對象進行刷新。
(2):checkCode();通過選擇器選擇id為"txt_code"的對象獲取參數,然后發送checeked.do請求調用Java程序進行校驗,如果驗證碼正確活動的data為 '驗證碼正確' 返回true,為空或者是 "驗證碼錯誤" 就是false。
function flushInamge(){ $("#code").attr("src","image.do?r"+Math.random());//實現局部刷新 }function checkCode(){ var check=true; //獲取用戶輸入的驗證碼信息 var code=$("#txt_code").val().trim(); if(code==''){ $("#s_code").html("驗證碼不能為空"); return false; } //驗證碼不為空就進行校驗 $.ajax({ url:"checked.do", type:"post", async:false, data:{"code":code}, dataType:"text", success:function(data){//data是服務器返回的消息 $("#s_code").html(data); if(data=='驗證碼錯誤'){check=false;} } }) return check;}
四:用Java對驗證碼進行校驗
通過request.getParameter("code");獲取ajax請求傳遞的參數,然后通過request.getSession().getAttribute("code");獲取session作用域中設置的參數,
最后通過if(code.equalsIgnoreCase(scode))無視大小寫對輸入的驗證碼和生成的驗證碼進行匹配相同out.print("驗證碼正確"),不相同out.print("驗證碼錯誤");將參數返回給ajax。
else if("/checked.do".equals(path)) { //接收請求code參數 String code=request.getParameter("code"); System.out.println("code"+code); //獲取session中驗證碼信息 String scode=(String) request.getSession().getAttribute("code"); System.out.println("scode"+scode); //比對輸出 response.setContentType("text/html;charset=UTF-8"); PrintWriter out=response.getWriter(); if(code.equalsIgnoreCase(scode)) { System.out.println(true); out.print("驗證碼正確"); }else { out.print("驗證碼錯誤"); System.out.println(false); } out.close();
效果
今年國慶假期終于可以憋在家里了不用出門了,不用出去看后腦了,真的是一種享受。這么好的光陰怎么浪費,睡覺、吃飯、打豆豆這怎么可能(耍多了也煩),完全不符合我們程序員的作風,趕緊起來把文章寫完。
這篇文章比較基礎,在國慶期間的業余時間寫的,這幾天又完善了下,力求把更多的前端所涉及到的關于文件上傳的各種場景和應用都涵蓋了,若有疏漏和問題還請留言斧正和補充。
以下是本文所涉及到的知識點,break or continue ?
原理很簡單,就是根據 http 協議的規范和定義,完成請求消息體的封裝和消息體的解析,然后將二進制內容保存到文件。
我們都知道如果要上傳一個文件,需要把 form 標簽的enctype設置為multipart/form-data,同時method必須為post方法。
那么multipart/form-data表示什么呢?
multipart互聯網上的混合資源,就是資源由多種元素組成,form-data表示可以使用HTML Forms 和 POST 方法上傳文件,具體的定義可以參考RFC 7578。
multipart/form-data 結構
看下 http 請求的消息體
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次請求要上傳文件,其中boundary表示分隔符,如果要上傳多個表單項,就要使用boundary分割,每個表單項由———XXX開始,以———XXX結尾。
每一個表單項又由Content-Type和Content-Disposition組成。
Content-Disposition: form-data 為固定值,表示一個表單元素,name 表示表單元素的 名稱,回車換行后面就是name的值,如果是上傳文件就是文件的二進制內容。
Content-Type:表示當前的內容的 MIME 類型,是圖片還是文本還是二進制數據。
解析
客戶端發送請求到服務器后,服務器會收到請求的消息體,然后對消息體進行解析,解析出哪是普通表單哪些是附件。
可能大家馬上能想到通過正則或者字符串處理分割出內容,不過這樣是行不通的,二進制buffer轉化為string,對字符串進行截取后,其索引和字符串是不一致的,所以結果就不會正確,除非上傳的就是字符串。
不過一般情況下不需要自行解析,目前已經有很成熟的三方庫可以使用。
至于如何解析,這個也會占用很大篇幅,后面的文章在詳細說。
使用 form 表單上傳文件
在 ie時代,如果實現一個無刷新的文件上傳那可是費老勁了,大部分都是用 iframe 來實現局部刷新或者使用 flash 插件來搞定,在那個時代 ie 就是最好用的瀏覽器(別無選擇)。
DEMO
這種方式上傳文件,不需要 js ,而且沒有兼容問題,所有瀏覽器都支持,就是體驗很差,導致頁面刷新,頁面其他數據丟失。
HTML
<form method="post" action="http://localhost:8100" enctype="multipart/form-data">
選擇文件:
<input type="file" name="f1"/> input 必須設置 name 屬性,否則數據無法發送<br/>
<br/>
標題:<input type="text" name="title"/><br/><br/><br/>
<button type="submit" id="btn-0">上 傳</button>
</form>
復制代碼
服務端文件的保存基于現有的庫koa-body結合 koa2實現服務端文件的保存和數據的返回。
在項目開發中,文件上傳本身和業務無關,代碼基本上都可通用。
在這里我們使用koa-body庫來實現解析和文件的保存。
koa-body 會自動保存文件到系統臨時目錄下,也可以指定保存的文件路徑。
然后在后續中間件內得到已保存的文件的信息,再做二次處理。
NODE
/**
* 服務入口
*/
var http=require('http');
var koaStatic=require('koa-static');
var path=require('path');
var koaBody=require('koa-body');//文件保存庫
var fs=require('fs');
var Koa=require('koa2');
var app=new Koa();
var port=process.env.PORT || '8100';
var uploadHost=`http://localhost:${port}/uploads/`;
app.use(koaBody({
formidable: {
//設置文件的默認保存目錄,不設置則保存在系統臨時目錄下 os
uploadDir: path.resolve(__dirname, '../static/uploads')
},
multipart: true // 開啟文件上傳,默認是關閉
}));
//開啟靜態文件訪問
app.use(koaStatic(
path.resolve(__dirname, '../static')
));
//文件二次處理,修改名稱
app.use((ctx)=> {
var file=ctx.request.files.f1;//得道文件對象
var path=file.path;
var fname=file.name;//原文件名稱
var nextPath=path+fname;
if(file.size>0 && path){
//得到擴展名
var extArr=fname.split('.');
var ext=extArr[extArr.length-1];
var nextPath=path+'.'+ext;
//重命名文件
fs.renameSync(path, nextPath);
}
//以 json 形式輸出上傳文件地址
ctx.body=`{
"fileUrl":"${uploadHost}${nextPath.slice(nextPath.lastIndexOf('/')+1)}"
}`;
});
/**
* http server
*/
var server=http.createServer(app.callback());
server.listen(port);
console.log('demo1 server start ...... ');
復制代碼
CODE
https://github.com/Bigerfe/fe-learn-code/
RequestMapping是一個用來處理請求地址映射的注解(將請求映射到對應的控制器方法中),可用于類或方法上。用于類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
RequestMapping請求路徑映射,如果標注在某個controller的類級別上,則表明訪問此類路徑下的方法都要加上其配置的路徑;最常用是標注在方法上,表明哪個具體的方法來接受處理某次請求。
@Controller @RequestMapping(value="/book") public class BookController { @RequestMapping(value="/title") public String getTitle(){ return "title"; } @RequestMapping(value="/content") public String getContent(){ return "content"; } }
由于BookController類加了value="/book"的@RequestMapping的注解,所以相關路徑都要加上"/book",即請求的url分別為:
(1)http://localhost:8080/book/title
(2)http://localhost:8080/book/content
"@RequestMapping"的value值前后是否有“/”對請求的路徑沒有影響,即value="book" 、"/book"、"/book/"其效果是一樣的。
value:指定請求的實際url
(1)普通的具體值。如前面的value="/book"。
(2)含某變量的一類值。
@RequestMapping(value="/get/{bookId}") public String getBookById(@PathVariable String bookId,Model model){ model.addAttribute("bookId", bookId); return "book"; }
路徑中的bookId可以當變量,@PathVariable注解即提取路徑中的變量值。
(3)ant風格
@RequestMapping(value="/get/id?"):可匹配“/get/id1”或“/get/ida”,但不匹配“/get/id”或“/get/idaa”;
@RequestMapping(value="/get/id*"):可匹配“/get/idabc”或“/get/id”,但不匹配“/get/idabc/abc”;
@RequestMapping(value="/get/id/*"):可匹配“/get/id/abc”,但不匹配“/get/idabc”;
@RequestMapping(value="/get/id/**/{id}"):可匹配“/get/id/abc/abc/123”或“/get/id/123”,也就是Ant風格和URI模板變量風格可混用。
(4)含正則表達式的一類值
@RequestMapping(value="/get/{idPre:\d+}-{idNum:\d+}"):可以匹配“/get/123-1”,但不能匹配“/get/abc-1”,這樣可以設計更加嚴格的規則。
可以通過@PathVariable 注解提取路徑中的變量(idPre,idNum)
(5)或關系
@RequestMapping(value={"/get","/fetch"} )即 /get或/fetch都會映射到該方法上。
method:指定請求的method類型, GET、POST、PUT、DELETE等;
@RequestMapping(value="/get/{bookid}",method={RequestMethod.GET,RequestMethod.POST})
params:指定request中必須包含某些參數值是,才讓該方法處理。
@RequestMapping(params="action=del"),請求參數包含“action=del”,如:http://localhost:8080/book?action=del
@RequestParam用于將請求參數區數據映射到功能處理方法的參數上。
public String requestparam1(@RequestParam String username)
請求中包含username參數(如/requestparam1?username=zhang),則自動傳入。
@RequestParam有以下三個參數:
value:參數名字,即入參的請求參數名字,如username表示請求的參數區中的名字為username的參數的值將傳入;
required:是否必須,默認是true,表示請求中一定要有相應的參數,否則將拋出異常;
defaultValue:默認值,表示如果請求中沒有同名參數時的默認值,設置該參數時,自動將required設為false。
public String requestparam4(@RequestParam(value="username",required=false) String username)
表示請求中可以沒有名字為username的參數,如果沒有默認為null,此處需要注意如下幾點:
原子類型:必須有值,否則拋出異常,如果允許空值請使用包裝類代替。
Boolean包裝類型:默認Boolean.FALSE,其他引用類型默認為null。
@PathVariable用于將請求URL中的模板變量映射到功能處理方法的參數上。
@RequestMapping(value="/users/{userId}/topics/{topicId}") public String test( @PathVariable(value="userId") int userId, @PathVariable(value="topicId") int topicId)
如請求的URL為“控制器URL/users/123/topics/456”,則自動將URL中模板變量{userId}和{topicId}綁定到通過@PathVariable注解的同名參數上,即入參后userId=123、topicId=456。
ModelAttribute可以應用在方法參數上或方法上,他的作用主要是當注解在方法參數上時會將注解的參數對象添加到Model中;當注解在請求處理方法Action上時會將該方法變成一個非請求處理的方法,但其它Action被調用時會首先調用該方法。
注釋一個方法
被@ModelAttribute注釋的方法表示這個方法的目的是增加一個或多個模型(model)屬性。這個方法和被@RequestMapping注釋的方法一樣也支持@RequestParam參數,但是它不能直接被請求映射。實際上,控制器中的@ModelAttribute方法是在同一控制器中的@RequestMapping方法被調用之前調用的。
被@ModelAttribute注釋的方法用于填充model屬性,例如,為下拉菜單填充內容,或檢索一個command對象(如,Account),用它來表示一個HTML表單中的數據。
一個控制器可以有任意數量的@ModelAttribute方法。所有這些方法都在@RequestMapping方法被調用之前調用。
有兩種類型的@ModelAttribute方法。一種是:只加入一個屬性,用方法的返回類型隱含表示。另一種是:方法接受一個Model類型的參數,這個model可以加入任意多個model屬性。
注解的使用場景
當@ModelAttribute注解用于方法時,與其處于同一個處理類的所有請求方法執行前都會執行一次此方法,這可能并不是我們想要的,因此,我們使用更多的是將其應用在請求方法的參數上,而它的一部分功能與@RequestParam注解是一致的,只不過@RequestParam用于綁定單個參數值,而@ModelAttribute注解可以綁定所有名稱匹配的,此外它自動將綁定后的數據添加到模型中,無形中也給我們提供了便利,這也可能是它命名為ModelAttribute的原因。
在默認情況下,ModelMap中的屬性作用域是request級別,也就是說,當本次請求結束后,ModelMap 中的屬性將銷毀。如果希望在多個請求中共享ModelMap中的屬性,必須將其屬性轉存到session 中,這樣 ModelMap 的屬性才可以被跨請求訪問。
Spring 允許我們有選擇地指定 ModelMap 中的哪些屬性需要轉存到 session 中,以便下一個請求屬對應的 ModelMap 的屬性列表中還能訪問到這些屬性。這一功能是通過類定義處標注 @SessionAttributes 注解來實現的。
package demo.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.SessionAttributes; import demo.model.User; @Controller @RequestMapping(value="/demo1") //(1)將ModelMap中屬性名為currUser的屬性放到Session屬性列表中,以便這個屬性可以跨請求訪問 @SessionAttributes("currUser") public class Demo1Controller { @RequestMapping(value="/getUser") public String getUser(ModelMap model){ User user=new User(); user.setUser_name("zhangsan"); user.setUser_age(25); user.setUser_email("zhangsan@sina.com"); //(2)向ModelMap中添加一個屬性 model.addAttribute("currUser",user); return "/demo/user"; } @RequestMapping(value="/getUser1") public String getUser1(ModelMap model){ User user=(User)model.get("currUser"); System.out.println(user.getUser_name()); System.out.println(user.getUser_age()); System.out.println(user.getUser_email()); return "demo/user1"; } }
我們在(2)處添加了一個 ModelMap 屬性,其屬性名為 currUser,而(1)處通過 @SessionAttributes 注解將 ModelMap 中名為 currUser 的屬性放置到 Session 中,所以我們不但可以在 getUser() 請求所對應的 JSP 視圖頁面中通過 request.getAttribute(“currUser”) 和 session.getAttribute(“currUser”) 獲取 user 對象,還可以在下一個請求(getUser1())所對應的 JSP 視圖頁面中通過 session.getAttribute(“currUser”) 或 session.getAttribute(“currUser”)訪問到這個屬性。
這里我們僅將一個 ModelMap 的屬性放入 Session 中,其實 @SessionAttributes 允許指定多個屬性。你可以通過字符串數組的方式指定多個屬性,如 @SessionAttributes({“attr1”,"attr2”})。此外,@SessionAttributes 還可以通過屬性類型指定要 session 化的 ModelMap 屬性,如 @SessionAttributes(types=User.class),當然也可以指定多個類,如 @SessionAttributes(types={User.class,Dept.class}),還可以聯合使用屬性名和屬性類型指定:@SessionAttributes(types={User.class,Dept.class},value={“attr1”,"attr2”})。
user.jsp頁面:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ page import="demo.model.User" %> <% String path=request.getContextPath(); String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> </head> <body><br> <%User user=(User)session.getAttribute("currUser");%> 用戶名:<%=user.getUser_name() %><br/> 年齡:<%=user.getUser_age() %><br/> 郵箱:<%=user.getUser_email() %><br/><br/> <a href="<%=path %>/demo1/getUser1">跳轉</a> </body> </html>
@Responsebody表示該方法的返回結果直接寫入HTTP response body中。一般在異步獲取數據時使用,在使用@RequestMapping后,返回值通常解析為跳轉路徑,加上@Responsebody后返回結果不會被解析為跳轉路徑,而是直接寫入HTTP response body中。比如異步獲取json數據,加上@Responsebody后,會直接返回json數據。
@RequestBody將HTTP請求正文插入方法中,使用適合的HttpMessageConverter將請求體寫入某個對象。
@RequestBody 將HTTP請求正文轉換為適合的HttpMessageConverter對象。
@ResponseBody 將內容或對象作為 HTTP 響應正文返回,并調用適合HttpMessageConverter的Adapter轉換對象,寫入輸出流。
@RequestBody
作用:
i) 該注解用于讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然后把相應的數據綁定到要返回的對象上;
ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
使用時機:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 可選(即非必須,因為這種情況的數據@RequestParam, @ModelAttribute也可以處理,當然@RequestBody也能處理);
multipart/form-data, 不能處理(即使用@RequestBody不能處理這種格式的數據);
其他格式, 必須(其他格式包括application/json, application/xml等。這些格式的數據,必須使用@RequestBody來處理);
B) PUT方式提交時, 根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 必須;
multipart/form-data, 不能處理;
其他格式, 必須;
說明:request的body部分的數據編碼格式由header部分的Content-Type指定;
@ResponseBody
作用:
該注解用于將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式后,寫入到Response對象的body數據區。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。