SpringMvc的Url對映和傳參案例
package sy.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;
import power.FuncConstants;
import power.Permission;
import sy.bean.TestPerson;
// 用來標註此類事springMVC管理的控制層的類
@Controller
// 為了防止多個控制層類有相同的方法所以要為每個控制層類起個唯一的標示名
@RequestMapping(value = "/test")
// @Scope("prototype") ,如果不加這個註釋那麼該controller就是單列的,一般我們不在controller當中定義成員變數所以不用加這個註釋,struts2中的action中會加這個註釋就是因為裡面經常會定義成員變數,如果不加這個註釋當有多個請求的時候就會照成資料共享錯誤
public class TestController {
@RequestMapping("/hello.do")
// 訪問此方法的url路徑/test/hello.do
public String hello() {
return "index";
}
// ===========================獲取頁面中傳進來的引數=======================================================
/**
* 方式一:通過request請求方式接收前臺頁面傳過來的引數
*/
@RequestMapping("/toPerson1.do")
// 訪問此方法的url路徑為/test/toPerson1.do
public String toPerson1(HttpServletRequest request) {
String name = request.getParameter("name");
System.out.println(name);
return "index";
}
/**
* 方式二:通過相匹配的引數列表接收頁面引數_String,
* 而且在頁面引數和引數列表中的引數型別相容的情況下是可以自動型別轉換的_Integer
* 時間型別如果傳入的時間格式比較特殊可以通過自定義專門的轉換器來解決(屬性編輯器)
*/
@RequestMapping("/toPerson2.do")
// 訪問此方法的url路徑為/test/toPerson2.do
public String toPerson2(String name, Integer age, Date birthday) {
System.out.println("姓名:" + name + ",年齡:" + age + ",生日" + birthday);
return "index";
}
/**
* 方式2.1 如果你頁面傳入的和用於接收的非要不一樣那麼可以用@RequestParam指定
*/
@RequestMapping("/toPerson21.do")
// 訪問此方法的url路徑為/test/toPerson21.do
public String toPerson21(@RequestParam("name") String userName, Integer age, Date birthday) {
System.out.println("姓名:" + userName + ",年齡:" + age + ",生日" + birthday);
return "index";
}
/**
* 註冊時間型別的屬性編輯器
*/
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
/**
* 方式三:如果頁面傳入的引數和接收的實體類(可以為多個實體)中set方法中的引數一致(首字母大小寫可以不一致),
* 那麼就可以直接給實體類的屬性賦值,沒有匹配上的將會被賦值為null
*/
@RequestMapping("/toPerson3.do")
// 訪問此方法的url路徑為/test/toPerson3.do
public String toPerson3(TestPerson p) {
System.out.println(p);
return "index";
}
/**
* 方式三:如過頁面傳來兩個同名的引數值,方法中可以用一個同名引數陣列去接收,而且接收到的引數順序和傳入時的相同。
* 如果沒有定義成陣列傳入的引數會以逗號分隔
*/
@RequestMapping("/toPerson4.do")
// 訪問此方法的url路徑為/test/toPerson4.do
public String toPerson4(String[] name) {
for (int i = 0; i < name.length; i++) {
System.out.println(name[i]);
}
return "index";
}
/**
* 方式四:指定form表單的請求方式,如果不指定,那麼post和get都可以訪問本方法
* desc:@RequestMapping( method=RequestMethod.POST )可以指定請求方式,前臺頁面就必須要以它制定好的方式來訪問,否則出現405錯誤
*/
@RequestMapping(value = "/toPerson5.do", method = RequestMethod.POST)
public String toPerson5(TestPerson person) {
System.out.println(person);
return "index";
}
// ===========================向頁面傳遞引數=======================================================
/**
* 方式一 desc:方法的返回值採用ModelAndView, new ModelAndView("index", map); ,相當於把結果資料放到request裡面
*/
@RequestMapping("/toPerson6.do")
public ModelAndView toPerson6() throws Exception {
TestPerson person = new TestPerson();
person.setName("james");
person.setAge(28);
person.setAddress("maami");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse("1985-04-22");
person.setBirthday(date);
Map<String, Object> map = new HashMap<String, Object>();
map.put("p", person);
return new ModelAndView("index", map);
}
/**
* 方式二 desc:直接在方法的引數列表中來定義Map,這個Map即使ModelAndView裡面的Map, 由檢視解析器統一處理,統一走ModelAndView的介面
*/
@RequestMapping("/toPerson7.do")
public String toPerson7(Map<String, Object> map) throws Exception {
TestPerson person = new TestPerson();
person.setName("james");
person.setAge(28);
person.setAddress("maami");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse("1985-04-22");
person.setBirthday(date);
map.put("p", person);
return "index";
}
/**
* 方式三 desc:在引數列表中直接定義Model,model.addAttribute("p", person);把引數值放到request類裡面去,建議使用
*/
@RequestMapping("/toPerson8.do")
public String toPerson8(Model model) throws Exception {
TestPerson person = new TestPerson();
person.setName("james");
person.setAge(28);
person.setAddress("maami");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse("1985-04-22");
person.setBirthday(date);
// 把引數值放到request類裡面去
model.addAttribute("p", person);
return "index";
}
// ===========================Ajax的使用=======================================================
/**
* 方式一 :ajax的請求返回值型別應該是void,引數列表裡直接定義HttpServletResponse, 獲得PrintWriter的類,最後可把結果寫到頁面
*/
@RequestMapping("/ajax.do")
public void ajax(String name, HttpServletResponse response) {
String result = "hello " + name;
try {
response.getWriter().write(result);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 方式二 :直接在引數的列表上定義PrintWriter,out.write(result);把結果寫到頁面,建議使用的
*/
@RequestMapping("/ajax1.do")
public void ajax1(String name, PrintWriter out) {
String result = "hello " + name;
out.write(result);
}
// ========================跳轉 轉發和重定向===================================
@RequestMapping("/redirectToForm.do")
public String redirectToForm() {
//同一個類中 desc:controller內部重定向,redirect:加上同一個controller中的requestMapping的值
return "redirect:upload.do";
//不同的類中 desc:controller之間的重定向:必須要指定好controller的名稱空間再指定requestMapping的值, redirect:後必須要加/,是從根目錄開始
// return "redirect:/test/toForm.do";
//同一個類中 desc:controller內部轉發,redirect:加上同一個controller中的requestMapping的值
// return "forward:toForm.do";
}
// ===========================檔案上傳========================
@RequestMapping("/upload.do")
// 訪問此方法的url路徑/test/hello.do
public String upload() {
return "fileUpload";
}
/**
* 檔案上傳方式一
* @param request
* @return
* @throws Exception
*/
@RequestMapping(value = "/fileUpload.do")
public String fileUpload(HttpServletRequest request) throws Exception {
// 第一步轉化request
MultipartHttpServletRequest rm = (MultipartHttpServletRequest) request;
// 獲得原始檔案
CommonsMultipartFile cfile = (CommonsMultipartFile) rm.getFile("pic");
// 獲得原始檔名
String origFileName = cfile.getOriginalFilename();
// 獲得原始檔案的字尾 XXX.jpg
String suffix = origFileName.contains(".") ? origFileName.substring(origFileName.lastIndexOf(".")) : "error";
if ("error".equalsIgnoreCase(suffix)) {
return "error";
}
// 獲得原始檔案的位元組陣列
byte[] bfile = cfile.getBytes();
// 新檔名=當前時間的毫秒數+3位隨機數
String fileName = String.valueOf(System.currentTimeMillis());
// 獲得三位隨機數
Random random = new Random();
for (int i = 0; i < 3; i++) {
fileName = fileName + random.nextInt(9);
}
// 拿到專案的部署路徑
String path = request.getSession().getServletContext().getRealPath("/");
// 將使用者上傳的檔案儲存到伺服器上
OutputStream out = new FileOutputStream(new File(path + "/upload/" + fileName + suffix));
IOUtils.write(bfile, out);
out.close();
return "success";
}
/**
* 檔案上傳方式二
* @param request
* @return
* @throws Exception
*/
@RequestMapping(value = "/fileUpload2.do")
public String fileUpload2(@RequestParam(value="pc",required=false) MultipartFile file,HttpServletRequest request) throws Exception {
if(file==null){
MultipartHttpServletRequest rm = (MultipartHttpServletRequest) request;
file=rm.getFile("pic");
}
String realPath=request.getSession().getServletContext().getRealPath("upload");
File destFile=new File(realPath+"/"+UUID.randomUUID().toString()+file.getName());
file.transferTo(destFile);//將上傳上來的臨時檔案移到到我們的目標目錄,File型別的也有類似的renameTo方法移動檔案
return "success";
}
}