Springmvc的基本使用,包括url映射、参数映射、页面跳转、ajax和文件上传
以前学习的时候写的代码案例,今天整理笔记的时候找到了,很久没有来园子了,发上来当个在线笔记用吧,免的时间长了又忘了
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"; } }