一、SpringMVC
1、helloworld 1、导包 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.2.RELEASE</version> </dependency> 2、在web.xml中配置 <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> 3、在springmvc.xml 中 <context:component-scan base-package="com.ibc.test"></context:component-scan><!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"></property> <property name="suffix" value=".jsp"></property> </bean>4、定义一个类用@Controller修饰,表示自动被扫描
定义一个带String返回值的方法 用@RequestMapping("/helloworld") 修饰 表示url地址 @Controller public class HelloWorld { @RequestMapping("/helloworld") public String sayHello(){ System.out.println("Hello MVC"); return "success"; } } [访问用helloworld.do] 返回页面 prefix+"success"+ suffix 做转发操作 5、index.jsp <a href="helloworld">helloworld</a> 2、RequestMapping 1、可以修饰方法,修饰类 url地址 = 修饰类的/修饰方法的 类上的路径默认是 / 方法是相对于类路径的。 value url 地址 2、提交方式 主要分为get,post RequestMethod.POST 或者 RequestMethod.GET 例如: @RequestMapping(value="/helloworld",method=RequestMethod.POST) 3、请求参数,请求头 了解 精确映射请求。 params 、heads 支持简单表达式 param1 表示请求必须包含这个参数 !param1 表示请求不能包含这个参数 param1=value1 表示包含这个参数,并且这个参数值必须为value1 param1!=value1 表示包含这个参数,并且这个参数不能为value1 可以是一个数组 {"param1=value1","param2"} 请求必须包含参数param1和param2 的两个请求参数,切param1参数的值必须为value1 例如: @RequestMapping(value="/helloworld",method=RequestMethod.GET, params={"username","age!=10"},headers={"Accept-Language=zh-CN,zh;q=0.8"}) 4、ant风格的url ? 任意一个字符 * 任意个字符 ** 多层路径 例如:@RequestMapping(value="user/**/helloworld")
表示跟路径下,user文件夹下,任意子文件夹,含有helloworld路径的url地址。 5、@PathVariable 注解 在url中可以使用占位符 {id} 作用:映射url中的占位符到目标方法的参数中。 如:@RequestMapping("/delete/{id}") 在方法参数中写@PathVariable("id") 注解修饰参数。 如: @RequestMapping("/delete/{id}") public String delete(@PathVariable("id") Integer id){ UserDao.delete(id); return "redirect:/user/list.action" } 6、REST 资源表现层转化 实例: /order/1 HTTP GET : 得到 id=1 的order get?id=1 /order/1 HTTP DELETE : 删除 id=1 的order /order/1 HTTP PUT : 更新 id=1 的order /order HTTP POST : 新建 一个 order HiddenHttpMethodFilter 这个过滤器会把post转换为put和delete请求。 1、tomcat需要在7以下版本测试,8及以上不好用。 2、在web.xml中配置HiddenHttpMethodFilter 过滤器 <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 3、在Action中书写四种不同的控制方法 通过@PathVariable 来获取id @RequestMapping(value="/testRest/{id}",method=RequestMethod.GET) public String testRest(@PathVariable Integer id){ System.out.println("get "+id); return "success"; } @RequestMapping(value="/testRest",method=RequestMethod.POST) public String testRest(){ System.out.println("post "); return "success"; } @RequestMapping(value="/testRest/{id}",method=RequestMethod.DELETE) public String testRestDelete(@PathVariable Integer id){ System.out.println("DELETE "+id); return "success"; } @RequestMapping(value="/testRest/{id}",method=RequestMethod.PUT) public String testRestPut(@PathVariable Integer id){ System.out.println("PUT "+id); return "success"; } 4、在JSP中写相关测试代码 <a href="testRest/1">helloworld</a> //get <br><br> <form action="testRest" method="post"> //post <input type="submit" value="post"> </form> <br><br> <form action="testRest/1" method="post"> //delete <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="DELETE"> </form> <br><br> <form action="testRest/1" method="post"> //put <input type="hidden" name="_method" value="PUT"> <input type="submit" value="put"> </form> <br><br> 7、@RequestParam 绑定请求参数 1、写一个Action @RequestMapping("/testRequestParam") public String testRequestParam(@RequestParam(value="username") String uname,@RequestParam("pass") Integer pass){ System.out.println(uname+" "+pass); return "success"; } 2、写一个测试JSP <a href="testRequestParam?username=tom&pass=123">testRequestParam</a> 3、@RequestParam(value="pass",required=false,defaultValue="0") Integer age 其中required默认是true 表示必须有,false表示可以没有。 age最好是Integer,如果是int最好设默认值。 defaultValue 表示默认值。 8、@RequestHeader 表示获取请求的头信息 1、写一个Action @RequestMapping("/testRequestHeader") public String testRequestHeader(@RequestHeader("Accept-Language") String header){ System.out.println("testRequestHeader "+header); return "success"; } 2、写一个jsp <a href="testRequestHeader">testRequestHeader</a> 9、@CookieValue 表示获取cookie信息 1、写一个Action @RequestMapping("/testRequestCookie") public String testRequestCookie(@CookieValue("JSESSIONID") String sessionid){ System.out.println("sessionid" +sessionid); return "success"; } 2、写一个jsp <a href="testRequestCookie">testRequestCookie</a> 10、使用POJO做参数 自动匹配 1、写一个Action @RequestMapping("/testStudent") public String testStudent(Student stu){ System.out.println(stu); return "success"; } 2、写一个jsp <a href="testStudent?stuid=111&stuname=jack&age=23&address.province=liaoning&address.city=shenyang">testStudent</a> 11、使用原生的request、response作为参数 springmvc支持的原生api HttpServletRequest,HttpServletResponse,HttpSession java.security.Principal Locale InputStream,OutputStream Reader,Writer 1、定义一个Action,附带中文处理 @RequestMapping("/testServletApi") public void testServletApi(HttpServletRequest request,HttpServletResponse response,OutputStream out) throws Exception{ System.out.println(request +" "+response); OutputStreamWriter osw=new OutputStreamWriter(out,"GBK"); BufferedWriter bw=new BufferedWriter(osw); bw.write("你好! 是mi"); bw.newLine(); bw.flush(); bw.close(); } 2、定义一个jsp调用 <a href="testServletApi">testServletApi</a> 12、ModelAndView springMVC会把ModelAndView里的数据放入到request域对象里面 1、定义一个Action @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ ModelAndView ret =new ModelAndView("success"); ret.addObject("time", new Date()); return ret; } 2、 定义一个JSP <a href="testModelAndView">testModelAndView</a> 3、定义success.jsp 在jsp指令元素中添加属性 isELIgnored="false" ${requestScope.time} 13、Map参数 处理模型数据的,数据放入request范围内。也可以是ModelMap、Model类型, 类似于ModelAndView 1、定义一个Action @RequestMapping("/testMap") public String testMap(Map map,Model model,ModelMap mmap){ model.addAttribute("age", 23); mmap.put("address", "beijing"); map.put("name", "tttom"); return "success"; } 2、定义一个jsp <a href="testMap">testMap</a> 3、修改success.jsp 在jsp指令元素中添加属性 isELIgnored="false" ${requestScope.name} ${requestScope.age} ${requestScope.address} 这里注意,map作为参数的主要作用是为了响应页面收集收据!!! 14、@SessionAttirbute ***只能放在类上面 表示那些属性放入session中 @SessionAttributes(value={"stus"},types={String.class}) 可以通过名字放入,也可以通过类型放入。同时写是或者的关系。 1、定义一个Action 类部分 @SessionAttributes({"stus"}) @Controller public class HelloWorld { 方法部分 @RequestMapping("/testSessionAttribute") public String testSessionAttribute(Map map){ Student stu=new Student(11, "tom", 21); map.put("stus", stu); return "success"; } 2、定义一个jsp <a href="testSessionAttribute">testSessionAttribute</a> 3、修改success.jsp 在jsp指令元素中添加属性 isELIgnored="false" ${requestScope.stus} ${sessionScope.stus} 两个范围都有数据。 15、@ModelAttribute *** 模拟拦截器功能 会在目标方法执行之前执行。 1、写一个Action @ModelAttribute public void getStu(@RequestParam(value = "stuid", required = false) Integer stuid,Map<String,Object> map) { if (stuid != null) { Student stu = new Student(1, "jack", 23); System.out.println(stu); map.put("student", stu); } System.out.println("getStu"); } 业务方法 @RequestMapping("/testModelAttribute") public String testModelAttribute(Student stu) { System.out.println(stu); return "success"; } ***这里注意:map.put("student", stu); key值是 方法参数的类型 2、写一个JSP <form action="testModelAttribute" method="post"> <input type="hidden" name="stuid" value="1" > username :<input type="text" name="stuname" value="Tom"> <br> <!-- age : <input type="text" name="age" value="23"><br> --> <input type="submit"> </form> -------------第二种用法 1、写一个Action @ModelAttribute public void getStu(@RequestParam(value = "stuid", required = false) Integer stuid,Map<String,Object> map) { if (stuid != null) { Student stu = new Student(1, "jack", 23); System.out.println(stu); map.put("abc", stu); } System.out.println("getStu"); } 业务方法 @RequestMapping("/testModelAttribute") public String testModelAttribute(@ModelAttribute("abc") Student stu) { System.out.println(stu); return "success"; } 注意: 这里map中的key值不是student了,改成了abc,只需在业务的方法中对参数做@ModelAttribute("abc") 注解修饰也可。 abc 就是key值 16、SpringMVC 确定POJO类型入参过程 1、确定一个key 1.1、若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名首字母小写, 1.2、若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值 2、在implicitModel中查找key对应的对象,若存在,则作为入参传入 3、若implicitModel中不存在key对应的对象,则检查档案的Handler是否使用@SessionAttirbute注解修饰, 若使用了该注解,且@SessionAttirbute注解的value属性值包含了key,则会从HttpSession中来获取key所 对应的value值,若存在则直接传入到目标方法的入参中,若不存在则抛出异常。 4、若Handler没有标识@SessionAttirbute注解或@SessionAttirbute注解的value值中不包含key,则 会通过反射来创建POJO类型的参数,传入为目标的方法 5、SpringMVC 会把key和value保存到implicitModel中,进而会保存到request中。 17、@SessionAttirbute 注解引发的异常 如果类上有 @SessionAttributes(value={"student"},types={String.class}) @Controller public class HelloWorld { 只有 @RequestMapping("/testModelAttribute") public String testModelAttribute( Student stu) { System.out.println(stu); return "success"; } 没有 @ModelAttribute public void getStu(@RequestParam(value = "stuid", required = false) Integer stuid,Map<String,Object> map) { if (stuid != null) { Student stu = new Student(1, "jack", 23); System.out.println(stu); map.put("student", stu); } System.out.println("getStu"); } 会报错,应为是先从session中取"student" 数据,没有报错,如果加上 @ModelAttribute 就可以了,它会先放入session中,再取出来。 3、视图和试图解析器 所有返回的类型,最终都被转换为ModelAndView ,通过视图解析器,得到最用的View视图。 1、<mvc:view-controller path="/success" view-name="success"/> 这个标签是通过url直接进入jsp页面,不通过Control。 注意:一旦这么配置后,success只能走url到jsp了,其他从url到control到jps都不好用了, 解决方案 增加一个标签 <mvc:annotation-driven></mvc:annotation-driven>,就都好用了 2、自定义视图 1、首先在springmvc.xml配置文件中添加 <!-- 使用view name 来解析视图 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="100"></property> </bean> order小的排在前面解析,默认是int的最大值。 2、写一个自定义的View @Component public class HelloView implements View { public String getContentType() { return "text/html"; } public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.getWriter().println("hello hello tom jack"); } } 其中,这个类一定要被IOC管理,所以写 @Component getContentType 这个方法返回的是响应页面的mime类型。 render 制作文件内容。 3、 测试 1、写一个Action @RequestMapping("/testView") public String testView(){ return "helloView"; } 2、写JSP <a href="testView">testView</a> 3、重定向或者转向 返回的字符串中 如果以forward:开始表示转向 返回的字符串中 如果以redirect:开始表示重定向 默认转向。 1、写一个Action @RequestMapping("/testRedirect") public String testRedirect(){ return "redirect:/success"; } 2、写一个JSP <a href="testRedirect">testRedirect</a> 4、REST风格项目注意 1、springMVC 本身没有导入JSTL,需要手动导入 <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> 2、 jsp中倒入标签 1、jstl标签导入 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2、springMVC 标签导入 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 针对form表单,必须在共享范围内具有对应的JavaBean 所以在Control类中,需要写一个 @ModelAttribute public void init(Map<String,Object> map){ map.put("student", new Student()); } 预先放入JavaBean。 3、目前只能访问Control,而普通的访问不了。 **处理静态资源方法 在springmvc.xml的配置文件中,添加 不影响正常的jsp访问 <mvc:default-servlet-handler/> 不影响正常的servlet访问,servlet没映射的用servlet默认处理 <mvc:annotation-driven></mvc:annotation-driven> 4、编辑时,不能使用url尽量使用绝对路径 5、编辑时,回显数据,不要用 <form:hidden path="_method" value="POST"/> 而需要使用 <input type="hidden" name="_method" value="POST"> 3、 / 和 /* 的区别 / 过滤Control /* 过滤所有url访问 4、类型解析器 1、自定义类型转换器 把一个String转换为Student对象 1、编写一个转换器类,实现org.springframework.core.convert.converter.Converter 这个接口 这个类要被IOC管理 public class StringToStudent implements Converter<String, Student>{ public Student convert(String arg0) { Student ret=null; if(arg0!=null){ String str[]=arg0.split("-"); if(str.length==3){ ret=new Student(33,str[0],Integer.parseInt(str[1]),str[2]); System.out.println(ret); } } return ret; } } 2、配置这个类到springMVC中 ,修改文件 springmvc.xml <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.ibc.student.tools.StringToStudent"></bean> </set> </property> </bean> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven> <mvc:default-servlet-handler/> 3、写一个JSP <a href="addStudent?student=tom-23-tianjin">查询addStudent</a> <br> 2、 annotation-driven 通常都需要加入这个配置。 3、@InitBinder 对WEbDataBinder对象初始化, 主要用于表单字段到JavaBean的绑定。 要求 @InitBinder 方法不能有返回值 @InitBinder 方法的参数,通常是WebDataBinder 如: @InitBinder public void initBinder(WebDataBinder binder){ // 表示在String到Student转换过程中,哪些属性不赋值 binder.setDisallowedFields("address"); } 1、写一个Action @InitBinder public void initBinder(WebDataBinder binder){ System.out.println("initBinder"); binder.setDisallowedFields("address"); } @RequestMapping(value="/addOne",method=RequestMethod.POST) public String addOne(Student stu,Map<String,Object> map){ map.put("studs", iStudentService.addOne(stu)); return "studentList"; } 2、写一个JSP <form action="addOne" method="post"> sname:<input type="text" name="sname"><br> sage:<input type="text" name="sage"><br> address:<input type="text" name="address"><br> <input type="submit" value="POST"> </form> 注意:操作要点 1、必须是表单自动转换JavaBean 4、数据格式化 string转换为Date 1、在配置文件里面必须有 <mvc:annotation-driven ></mvc:annotation-driven> 只能这样。 2、在实体类中对应的属性添加注解 @DateTimeFormat(pattern="yyyy-MM-dd") private Date birthday; 3、写一个Action文件 @RequestMapping(value="/addOne",method=RequestMethod.POST) public String addOne(Student stu,Map<String,Object> map){ map.put("studs", iStudentService.addOne(stu)); return "studentList"; } 4、写一个JSP文件 <form action="addOne" method="post"> sname:<input type="text" name="sname"><br> sage:<input type="text" name="sage"><br> address:<input type="text" name="address"><br> birthday:<input type="text" name="birthday"><br> <input type="submit" value="POST"> </form> 其中birthday 部分输入2000-3-4 进行验证。 string转换为float 1、同上 2、 @NumberFormat(pattern="###,###,###.##") private Float salary; 3、4 注意: 如果即想要数据格式化有想用自己的类型转换器好用。 1、修改配置文件 <mvc:annotation-driven conversion-service="conversionService" ></mvc:annotation-driven> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.ibc.student.tools.StringToStudent"></bean> </set> </property> </bean> 注意:类型改变了,变为FormattingConversionServiceFactoryBean 5、 类型转换错误 1、需要Action中添加参数 @RequestMapping(value="/addOne",method=RequestMethod.POST) public String addOne(Student stu,BindingResult result,Map<String,Object> map){ System.out.println("-------addOne-------"); if(result.getErrorCount()>0){ for (FieldError error : result.getFieldErrors()) { System.out.println(error.getObjectName()+" "+error.getDefaultMessage()); } } map.put("studs", iStudentService.addOne(stu)); return "studentList"; } *****特别注意:Student stu,BindingResult result 这两个参数必须挨着 6、数据校验 1、添加jar包 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator-annotation-processor</artifactId> <version>6.0.0.Alpha1</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency>注意,这里面el-api 可能会与tomcat中的jar包冲突。
2、在实体类的属性上修饰 @NotEmpty private String sname; 3、在Control上的方法属性做修饰 @RequestMapping(value="/addOne",method=RequestMethod.POST) public String addOne(@Valid Student stu,BindingResult result,Map<String,Object> map){ 注意 @Valid Student stu,BindingResult result 挨着 4、出错去的页面 @ModelAttribute public void init(Map<String,Object> map){ map.put("student", new Student()); } @RequestMapping(value="/addOne",method=RequestMethod.POST) public String addOne(@Valid Student stu,Errors result,Map<String,Object> map){ map.put("student", stu); if(result.getErrorCount()>0){ for (FieldError error : result.getFieldErrors()) { System.out.println(error.getObjectName()+" "+error.getDefaultMessage()); } return "index"; } return "redirect:/searchAll"; } 5、在错误页面 <form:form action="addOne" method="post" modelAttribute="student"> <form:errors path="*"></form:errors> <br> sname:<form:input path="sname"/><form:errors path="sname"></form:errors><br> address:<form:input path="address"/><br> sage:<form:input path="sage"/><br> birthday:<form:input path="birthday"/><form:errors path="birthday"></form:errors><br> salary:<form:input path="salary"/><form:errors path="salary"></form:errors><br> <form:button >tijiao</form:button> </form:form> 注意:<form:errors path="*"></form:errors> 一定要放在<form:form action="addOne" method="post" modelAttribute="student">中。 path可以是属性名,也可以是* ,*代表全部 7、国际化 1、编写一个属性文件叫i8n.property NotEmpty.student.sname=sname \u4E0D\u80FD\u4E3A\u7A7A\uFF01 注意,NotEmpty 表示注解类名 student 是实体类在IOC中的名字 sname 是类的属性名 2、配置国际化文件,在spring的配置文件中 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> </bean> 3、_en _zh_CN 不好用 8、返回JSON数据 1、引入jar包 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0.pr2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0.pr2</version> </dependency> 2、写一个Action @ResponseBody @RequestMapping("/testJSON") public List<Student> testJSON(){ return iStudentService.findAll(); } 3、写一个JSP <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript"> $(function(){ $("#testjson").click(function(){ var url=this.href; var args={}; $.post(url,args,function(data){ var str=""; for(var i=0;i<data.length;i++){ var sid=data[i].sid; var sname=data[i].sname; var sage=data[i].sage; var address=data[i].address; var salary=data[i].salary; var birthday=data[i].birthday; str+=sid +"\t"+sname+"\t"+sage+"\t"+address+"\t"+salary+"\t"+birthday+"\n"; } alert(str); }); return false; }); })() </script> <a href="testJSON" id="testjson">testJSON</a> 4、文件上传 1、写一个JSP <form action="testUpload" method="post" enctype="multipart/form-data" > file:<input type="file" name="file"><br> desc:<input type="text" name="desc"><br> <input type="submit"> </form> 2、写一个Action @ResponseBody @RequestMapping("/testUpload") public String testUpload(@RequestBody String body){ System.out.println(body); return "hello hahaha"+new Date(); } 注意: @RequestBody String body 表示输入参数 里面有表单的所有数据 @ResponseBody 表示响应内容 自动识别类型。例子中响应一个网页字符串。 5、文件下载 1、准备一个文件 download/message.txt 2、写一个Action @RequestMapping("/testDownLoad") public ResponseEntity<byte[]> testDownLoad(HttpSession session) throws Exception{ //获取文件byte[] ServletContext context = session.getServletContext(); InputStream is = context.getResourceAsStream("/download/message.txt"); byte[] body=new byte[is.available()]; is.read(body); //下载头文件 HttpHeaders headers=new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=abc.txt"); //获取http状态 HttpStatus statusCode=HttpStatus.OK; //利用ResponseEntity 实现下载 ResponseEntity<byte[]> ret=new ResponseEntity(body, headers, statusCode); return ret; } 3、写一个JSP <a href="testDownLoad" >testDownLoad</a> 6、国际化 1、页面依据浏览器语言设置,对页面文本、时间、数值进行本地化处理。 使用JSTL的fmt标签就可 1、在配置文件中,添加 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> </bean> 2、写两个属性文件 i18n_en_US.properties i18n.user=User i18n.password=Password i18n_zh_CN.properties i18n.user=\u7528\u6237\u540D i18n.password=\u5BC6\u7801 3、写一个JSP文件 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <form action="testGjh" method="post"> <fmt:message key="i18n.user"></fmt:message> <input type="text" name="user"><br> <fmt:message key="i18n.password"></fmt:message> <input type="text" name="password"><br> <input type="submit"> </form> 4、验证 用ie浏览器,通过改变语言设置,看变化 工具--》Internate选项--》语言 2、可以在Bean中,获取Locale对应的消息 注入对应的实例就可。 在第一步的基础上, 写一个Aciton 1、属性注入国际化资源 @Autowired private ResourceBundleMessageSource messageSource; 2、在Action中 @RequestMapping("/testGjh") public String testGjh(Locale locale){ System.out.println(messageSource.getMessage("i18n.user", null, locale)); return "gjh"; } 注意,可以接参数。locale 作为参数传递过来。 3、可以通过超链接,切换Locale,不依赖浏览器设置 配置LocalResoler和LocaleChangeIntercepteor 1、在配置文件中添加配置 <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> <mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> 2、在JSP中 <a href="testGjh?locale=zh_CN">中文</a> <a href="testGjh?locale=en_US">英文</a> 注意,传递一个参数locale即可。 7、文件上传 1、添加jar包 <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> 2、写一个JSP <form action="testUpload2" method="post" enctype="multipart/form-data" > file:<input type="file" name="file"><br> desc:<input type="text" name="desc"><br> <input type="submit"> </form> 3、写一个Action @RequestMapping("/testUpload2") public String testUpload2(@RequestParam("desc") String desc,@RequestParam("file") MultipartFile file,HttpSession session) throws Exception{ InputStream is = file.getInputStream(); FileOutputStream fos=new FileOutputStream(session.getServletContext().getRealPath("download")+"/"+file.getOriginalFilename()); FileCopyUtils.copy(is, fos); return "index"; } 注意: 1、页面中file的类型为MultipartFile 2、获取输入流 InputStream is = file.getInputStream(); 3、获取输出流 FileOutputStream fos=new FileOutputStream(session.getServletContext().getRealPath("download")+"/"+file.getOriginalFilename()); 4、 利用工具类实现copy FileCopyUtils.copy(is, fos); 8、拦截器 1、自定义拦截器 helloworld 1、写一个拦截器类 public class FirstInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor preHandle"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor afterCompletion"); } } 注意: 1、preHandle这个方法是第一个被调用的,如果返回false,下面两个方法不调用了, 如果返回true,下面两个方法被调用 做权限处理 2、postHandle,这个方法是在调用目标方法之后,页面显示之前调用。 往request里面放数据 3、afterCompletion ,这个方法是在显示页面之后调用。 释放资源 2、配置拦截器 在配置文件里面,添加拦截器 <mvc:interceptors> <bean class="com.ibc.student.interceptor.FirstInterceptor"></bean> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> 3、指定拦截或者不拦截的设定 指定拦截 <mvc:interceptors> <bean class="com.ibc.student.interceptor.FirstInterceptor"></bean> <mvc:interceptor> <mvc:mapping path="/addOne"/> <bean class="com.ibc.student.interceptor.SecondInterceptor"></bean> </mvc:interceptor> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> SecondInterceptor 只拦截/addOne 路径 ,其他不拦截, 或者配置,哪些不拦截,其他拦截 <mvc:exclude-mapping path="/testGjh"/> <mvc:interceptors> <bean class="com.ibc.student.interceptor.FirstInterceptor"></bean> <mvc:interceptor> <mvc:exclude-mapping path="/testGjh"/> <bean class="com.ibc.student.interceptor.SecondInterceptor"></bean> </mvc:interceptor> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> 9、异常处理 1、在配置文件添加 <mvc:annotation-driven ></mvc:annotation-driven> 2、写一个测试的JSP <a href="testException?i=0">testException</a> 3、定义一个错误JSP,error.jsp 4、在action中定义 业务方法 @RequestMapping("/testException") public String testException(@RequestParam("i") Integer i){ System.out.println("num="+(10/i)); return "index"; } 错误处理方法 @ExceptionHandler(value={ArithmeticException.class}) public String goError(Exception ex){ System.out.println(ex); return "error"; } 注意: 1、@ExceptionHandler(value={ArithmeticException.class}) value是接受的异常类型数组。 2、方法中,不能接map类型的参数。如果想向error页面传递数据,要用ModelAndView 把第四步改写 @ExceptionHandler(value={ArithmeticException.class}) public ModelAndView goError(Exception ex){ ModelAndView ret =new ModelAndView("error"); ret.addObject("exception", ex); System.out.println(ex); return ret; } 修改错误页面 添加isELIgnored="false" 属性 添加 ${exception } 内容 4、设置全局exception 写一个类,用@ControllerAdvice修饰类, 做全局处理, 处理异常顺序,先自己的,自己的找不到,找@ControllerAdvice 修饰的。 如: @ControllerAdvice public class HandleException { @ExceptionHandler(value={ArithmeticException.class}) public ModelAndView goError(Exception ex){ ModelAndView ret =new ModelAndView("error"); ret.addObject("exception", ex); System.out.println(ex); return ret; } } 10、定制异常状态码和内容 1、写一个自定义异常,设置异常码和错误信息 @ResponseStatus(value=HttpStatus.FORBIDDEN,reason="我的错误") public class MyException extends RuntimeException { private static final long serialVersionUID = 1L; } 2、写一个JSP <a href="testHttpStatus?i=0">testHttpStatus?i=0</a> 3、写一个Action @RequestMapping("/testHttpStatus") public String testHttpStatus(@RequestParam("i") Integer i){ if(i==0){ throw new MyException(); } return "index"; } 11、配置异常,指定异常到指定页面 1、写配置文件,表示页面出现java.lang.ArrayIndexOutOfBoundsException 自动进入error.jsp页面 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop> </props> </property> </bean> 在异常页面自动有exception对象。