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"; } }