学习springmvc

tech2024-09-30  19

springmvc学习

一、springmvc的配置步骤(通过maven)

1、新建项目

File ->newProject

设置项目属性 最后点击Finish

2、配置pox.xml获取所需的jar包

<properties> <spring.version>5.0.2.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> </dependencies>

若嫌弃下载太慢可通过在maven->conf->setting.xml的mirrors标签中添加国内镜像即可。

3、新建目录

等所需jar包都通过maven下载好后 在main目录下新建java文件加和resources文件夹,并设置通过鼠标右击文件夹mark Directory as选择对应功能的文件夹。java文件夹用于存放代码,resources文件夹用于存放配置文件

4、配置springmvc配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注解扫描 --> <context:component-scan base-package="com.test.springnvc"></context:component-scan> <!-- 视图解析器 --> <!-- 处理方式 /WEB-INF/views/+index+.jsp --> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 开启springmvc框架的支持 --> <mvc:annotation-driven></mvc:annotation-driven> </beans>

完成以上步骤即可开始编写代码

二、注释的使用

private static final String SUCCESS = "success";

1、@RequestMapping映射信息

/** * 1、@RequestMapping 除了可以用来修饰方法还可以用来修饰类 * 2、类定义处:提供初步的请求映射信息。相对于web应用的根目录 * 方法处:提供进一步细分映射信息。相对于类定义处的URL。 * 若类定义处未标注@RequestMapping,则方法处标记的URL相对于web应用的根目录 * @return */ @RequestMapping(path = "hello") public String sayHello(){ System.out.println("HelloWorld"); return SUCCESS; }

2、使用Method的方式来决定请求方式

/** * 使用Method的方式来决定请求方式 * @return */ @RequestMapping(value="/testMethod",method= RequestMethod.POST) public String testMethod(){ System.out.println("testMethod"); return SUCCESS; } /* 接受请求必须使用post方式 */

3、可以使用params和headers来精确的映射请求

/** * 可以使用params和headers来更加精确的映射请求, * params和headers 支持简单的表达式 * @return */ @RequestMapping(value="testParamsAndHeaders",params = {"username","password!=1234"},headers = {}) public String testParamsAndHeaders(){ System.out.println("testParamsAndHeaders"); return SUCCESS; } /* 接受请求必须满足所带参数包含username,以及password,并且password不能为1234 若headers有条件同理 */

4、@RequestMapping支持Ant风格的URL

/** * -@RequestMapping支持Ant风格的URL * * 匹配文件名中的任意字符 * ** 匹配多层路径 * ? 匹配文件名中的一个字符 * @return */ @RequestMapping("/testAntPath/*/abc") public String testAntPath(){ System.out.println("testAntPath"); return SUCCESS; } /* 可以通过http://localhost:8080/springmvc_test/testAntPath/asdas/abc 或者是http://localhost:8080/springmvc_test/testAntPath/asdqweqas/abc等请求 */

5、@PathVariable的应用

/** * -@PathVariable 可以映射URL中的占位符到目标方法的参数中 * @return */ @RequestMapping("/testPathVariable/{id}") public String testPathVariable(@PathVariable("id")String url){ System.out.println("testPathVariable"+"---"+url); return SUCCESS; } /* 即假如URL为 http://localhost:8080/springmvc_test/testPathVariable/123 则控制台会输出 testPathVariable---123 */

6、Rest风格的URL

/** * Rest风格的URL * 以CRUD 为例: * 新增: /order POST * 修改: /order/1 PUT update?id=1 * 获取: /order/1 GET get?id=1 * 删除: /order/1 DELETE delete?id=1 * * 如何发送 PUT 请求和 DELETE 请求呢? * 1、需要配置HiddenHttpMethodFilter * 2、需要发送 POST 请求 * 3、需要在发送 POST 请求时携带一个 name="_method" 的隐藏域,value要等于 DELETE 或 PUT * */ @RequestMapping(value = "/testRestPUT/{id}",method = RequestMethod.PUT) public String testRestPUT(@PathVariable("id") String id){ System.out.println("testRest PUT: " + id); return SUCCESS; } @RequestMapping(value = "/testRestDelete/{id}",method = RequestMethod.DELETE) public String testRestDelete(@PathVariable("id") String id){ System.out.println("testRest DELETE: " + id); return SUCCESS; } @RequestMapping(value = "/testRestPost",method = RequestMethod.POST) public String testRestPost(){ System.out.println("testRest POST: "); return SUCCESS; } @RequestMapping(value = "/testRestGet/{id}",method = RequestMethod.GET) public String testRestGet(@PathVariable("id") String id){ System.out.println("testRest GET: " + id); return SUCCESS; }

三、参数的使用

1、@RequestParam

/** * -@RequestParam 来映射请求参数 * value 请求参数参数名 * required 该请求参数是否是必须的,默认为true * defaultValue 请求参数默认值 * */ @RequestMapping("/testRequestParam") public String testRequestParam(@RequestParam(value = "username")String username ,@RequestParam(value = "age",required = false,defaultValue = "0") int age){ System.out.println("testRequestParam:username = "+username+",age = "+age); return SUCCESS; }

2、@RequestHeader

/** * -@RequestHeader 映射请求头文件信息 */ @RequestMapping("/testRequestHeader") public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al){ System.out.println("testRequestHeader: Accept-Language = "+al); return SUCCESS; }

3、@CookieValue

/** * -@CookieValue 映射一个cookie值 * 属性同@RequestParam */ @RequestMapping("/testCookieValue") public String testCookieValue(@CookieValue("JSESSIONID")String sessionId){ System.out.println("testCookieValue: JSESSIONID = "+sessionId); return SUCCESS; }

4、POJO类作为参数

/** * SpringMvc会按参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。 * 支持级联属性。 */ @RequestMapping("/testPOJO") public String testPOJO(User user){ System.out.println("testPOJO: " + user); return SUCCESS; } <form action="springmvc/testPOJO" method="post"> username:<input type="text" name="username"/><br> password:<input type="password" name="password"/><br> age:<input type="text" name="age"/><br> city:<input type="text" name="address.city"/><br> province:<input type="text" name="address.province"/><br> <input type="submit" value="submit"/> </form>

user类 Address类

5、使用Servlet原生API作为参数

/** * 可以使用Servlet原生api作为目标放大和参数 * 具体支持一下类型: * HttpServletRequest * HttpServletResponse * HttpSession * java.security.Principal * Locale InputStream * OutputStream * Reader * Writer */ @RequestMapping("/testServletApi") public String testServletApi(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Writer out){ System.out.println("testServletApi"); return SUCCESS; }

四、处理模型数据

1、ModelAndView

/** * 目标的返回值可以是ModelAndView类型 * 其中可以包含视图和模型信息 * SpringMvc会把ModelAndView的model中数据放到request域对象中 */ @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ String view = SUCCESS; ModelAndView modelAndView = new ModelAndView(view); modelAndView.addObject("time" ,new Date()); return modelAndView; }

结果

2、Map

/** * 目标方法可以添加map类型(实际也可以是model类型或者modelmap类型)的参数 */ @RequestMapping("/testMap") public String testMap(Map<String,Object> map){ System.out.println(map.getClass().getName()); map.put("names", Arrays.asList("zhangsan","lisi","wangwu")); return SUCCESS; }

结果

3、@SessionAttributes

@SessionAttributes(value = {"user"},types = {String.class}) @Controller public class HelloWorldController { /** * -@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(value) * 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types) * * 注意:改注解只能放在类的上面。而不能修饰方法。 */ @RequestMapping("/testSessionAtrribute") public String testSessionAtrribute(Map<String,Object> map){ map.put("user" ,new User("zhangsan","12345",12,new Address("xiamen","fujian"))); map.put("string","abcdef"); return SUCCESS; } }

结果

4、ModelAttribute

分析ModelAttribute笔记

/** * 1、-@ModelAttribute 被这个标记的方法,会在每一个目标方法执行之前被SpringMvc调用! * 2、@ModelAttribute 注解也可以来修饰目标方法POJO类型的入参,其value属性值有如下作用: * 1).SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参当中 * 2).SpringMVC会以value为key,POJO类型对象为value,存入到request中 */ @ModelAttribute public void getStu(@RequestParam(value = "id",required = false) Integer id,Map<String,Object> map){ System.out.println("modelAttribute method"); if(id != null){ //模拟从数据库中获取对象 Student student = new Student(1,"zhangsan","123456",12); System.out.println("从数据库中获取对象"+student); map.put("stu",student); } } /** -@ModelAttribute运行流程 * 1、执行@ModelAttribute注解修饰的方法:从数据库取出对象,把对象放入到了Map中。键为student * 2、SpringMVC 从Map中取出Student对象,并把表单参数赋值给该Student对象的对应属性。 * 3、SpringMVC 把上述对象传入目标方法的参数。 * * 注意:在@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致 * */ @RequestMapping("/testModelAttribute") public String testModelAttribute(@ModelAttribute("stu") Student student){ System.out.println("testModelAttribute update :"+student); return SUCCESS; }

前端视图

<form action="springmvc/testModelAttribute" method="post"> <input type="hidden" name="id" value="1"/> name:<input type="text" name="name" value="zhangsan"/><br> age:<input type="text" name="age" value="12"/><br> <input type="submit" value="submit"/> </form>

输入 结果

五、其他

1、SpringMVC国际化

1)写好国际化的properties文件 2)用ResourceBundleMessageSource在spring配置文件中配置国际化资源文件

<!-- 配置国际化资源文件 --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> <!-- 支持UTF-8的中文 --> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean>

3)jsp页面使用fmt标签

<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%> <%@ page isELIgnored="false" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>> <html> <head> <title>Title</title> </head> <body> <fmt:message key="i18n.username"></fmt:message> <br><br> <fmt:message key="i18n.password"></fmt:message> </body> </html>

4)结果 乱码的解决方式 i18n_zh_CN

i18n.username = 用户名 i18n.password = 密码

i18n_en_US

i18n.username = username i18n.password = password

2、mvc:view-controller标签

<!-- 配置直接转发页面 --> <!-- 可以直接转发相应的页面,而无需通过handler的方法 --> <mvc:view-controller path="/success" view-name="success"/> <!-- 在实际开发中通常都需配置mvc:annotation-driven 标签 --> <!-- 开启springmvc框架的支持 --> <mvc:annotation-driven></mvc:annotation-driven>

3、自定义视图

1)java类实现View

@Component public class HelloView implements View { /** * 返回内容类型 */ @Override public String getContentType() { return "text/html"; } /** * 渲染视图 */ @Override public void render(Map<String, ?> map, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { httpServletResponse.getWriter().println("Hello view, time : " + new Date()); } }

2)在Spring配置文件中配置视图解析器

<!-- 通过配置BeanNameViewResolver解析器:使用视图名字来解析视图 --> <!-- 通过order属性来定义视图解析器的优先级,order值越小优先级越高 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="100"></property> </bean>

3)结果

4、重定向

/** * 如果返回字符串中带 forward: 或 redirect: 前缀时SpringMVC会对他们进行特殊处理 * forward: 转发 * redirect: 重定向 */ @RequestMapping("/testRedirect") public String testRedirect(){ System.out.println("testRedirect"); return "redirect:/index.jsp"; }

六、利用HiddenHttpMethodFilter模拟CRUD操作

1、在web.xml中配置HiddenHttpMethodFilter拦截器

<!-- 配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转为DELETE或PUT请求 --> <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>

2、配置对应的控制器

@Controller public class StudentController { @Autowired StudentDAO studentDAO; @Autowired TeacherDAO teacherDAO; @ModelAttribute public void getStudent(@RequestParam(value = "sno",required = false) String sno,Map<String,Object> map){ if(sno != null){ map.put("student",studentDAO.getStuBySno(sno)); } } //更新学生数据操作 @RequestMapping(value = "/stu",method = RequestMethod.PUT) public String update(Student student){ studentDAO.saveStu(student); return "redirect:/stus"; } //进入编辑学生界面 @RequestMapping(value = "/stu/{sno}",method = RequestMethod.GET) public String input(@PathVariable("sno") String sno,Map<String,Object> map){ map.put("student",studentDAO.getStuBySno(sno)); map.put("teachers",teacherDAO.getTeachers()); return "input"; } //所有学生列表 @RequestMapping("/stus") public String list(Map<String, Object> map){ map.put("students",studentDAO.getAllStu()); return "list"; } //进入添加页面 @RequestMapping(value="/stu",method = RequestMethod.GET) public String input(Map<String,Object> map){ map.put("teachers",teacherDAO.getTeachers()); map.put("student",new Student()); return "input"; } //添加学生操作 @RequestMapping(value="/stu",method = RequestMethod.POST) public String insertStu(Student student){ studentDAO.addStu(student); return "redirect:/stus"; } //删除学生操作 @RequestMapping(value = "/stu/{sno}",method = RequestMethod.DELETE) public String deleteStu(@PathVariable("sno") String sno){ studentDAO.deleteStuBySno(sno); return "redirect:/stus"; } }

3、解决中文乱码问题

在web.xml中配置CharacterEncodingFilter拦截器修改编码方式

<!--springmvc提供的解决post/get请求参数中文乱码问题--> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

4、页面中表单回显

<!-- 1、为什么使用form(springmvc)标签呢? 可以更快速的开发出表单页面,而且可以更方便的进行表单回显 2、注意: 可以通过ModelAttribute属性指定绑定的模型属性 若没有指定该属性,则默认request域对象中读取command的表单bean,如果该属性值也不存在,则会发生错误。 --> <!-- springmvc表单标签默认回显 --> <form:form action="${pageContext.request.contextPath}/stu" method="post" modelAttribute="student"> <!-- path属性对应html表单标签的name属性值 --> <c:if test="${student.sno == null}"> name:<form:input path="name"/><br> </c:if> <c:if test="${student.sno != null}"> <form:hidden path="sno"/><br> <input type="hidden" name="_method" value="PUT"/> </c:if> age:<form:input path="age"/><br> mark:<form:input path="mark"/><br> teacher: <form:select path="teacherno" items="${teachers}" itemLabel="name" itemValue="teacherno"></form:select><br> <input type="submit" value="submit"/><br> </form:form>

七、数据操作

1、数据类型转换

必做操作 配置mvc:annotation-driven

<mvc:annotation-driven></mvc:annotation-driven>

前端界面(包括输入)

1)在spring配置文件中配置类型转换器

<!-- 配置ConversionService类型转换器 所有注册的Converter实例对象都可以在RequestParamMethodArgumentResolverd的binder属性中的conversionServices属性中查看到 用FormattingConversionServiceFactoryBean 既可以添加自定义的类型转换器,又可以使用springmvc提供的格式化作用 --> <bean id="conversionService2" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <ref bean="studentServiceConverer"></ref> </set> </property> </bean>

2)自定义类型转换器

@Component public class StudentServiceConverer implements Converter<String, Student> { /** * 将输入数据转化为学生类 */ @Override public Student convert(String source) { if(source != null){ String[] vals = source.split("-"); // T003-2116062-王五-11-66 if(vals.length == 5){ String teacherno = vals[0]; String sno = vals[1]; String name = vals[2]; Integer age = Integer.parseInt(vals[3]); Integer mark = Integer.parseInt(vals[4]); Student student = new Student(teacherno,sno,name,age,mark); return student; } } return null; } }

3)将刚刚配置的类型转换器配置到注解驱动中

<mvc:annotation-driven conversion-service="conversionService2"></mvc:annotation-driven>

4)InitBinder注解

// @InitBinder // public void initBinder(WebDataBinder binder){ // //设置在表单对javabean进行赋值时那个值不进行赋值 // binder.setDisallowedFields("name"); // }

2、数据格式化

1、配置mvc:annotation-driven 2、表明注解

@DateTimeFormat(pattern = "yyyy-MM-dd") private Date brith; @NumberFormat(pattern = "#.##m") private Float high;

3、数据校验

JSR 303标准注解说明

1)步骤

①使用JSR 303验证标准 ②加入 hibernate validator验证框架 ③在springmvc配置文件中加入<mvc:annotation-driven/> <mvc:annotation-driven/> 会默认装配好一个LocalValidatorFactoryBean ④需要在bean的属性上配置对应的注解 ⑤在目标方法bean类型的前面添加@Valid注解

2)maven配置

<!-- JSR 303 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.1.1.GA</version> </dependency> </dependencies>

3)注解配置

@NotEmpty private String name; @Max(100) @Min(0) private Integer mark; @Past @DateTimeFormat(pattern = "yyyy-MM-dd") private Date brith;

在目标方法bean类型前添加@Valid

public String insertStu(@Valid Student student, BindingResult bindingResult,Map<String,Object> map)

4)运行效果

4、错误消息显示及国际化

1)错误消息显示

<!-- 用于在页面上显示错误消息的信息 path属性 对应的错误信息,*代表显示全部错误信息 --> <form:errors path="*"></form:errors>

2)配置国际化properties文件

#注解类型(要与数据校验中的注释配置对应).目标方法的类名(在request中的类名,或者被modelAttribute修饰的类名).对象属性名 NotEmpty.student.name = name不存在 Max.student.mark = mark不能大于100 Min.student.mark = mark不能小于0 Past.student.birth = birth不能是未来日期 #typeMismatch 在数据绑定时,数据类型不匹配时发生错误 #methodInvocation springmvc在调用处理方法时发生错误 typeMismatch.student.birth = 不是一个日期 typeMismatch.student.high = 不是一个升高

3)结果

八、返回数据处理

1、返回Json

1)导入jackson相关jar包

<!--Jackson required包--> <!-- jackson包可能不兼容会导致 Servlet.init() for servlet DispatcherServlet threw exception --> <dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.8</version> </dependency>

2)配置@ResponseBody注解

@ResponseBody @RequestMapping("testJson") public Collection<Student> testJson(){ return studentDAO.getAllStu(); }

3)返回结果

2、HttpMessageConverter

1)原理图

通过HttpMessageConverter转化为对应的对象然后转化为对应的输入输出流

2)使用

下载文件效果 httpHeader详解

/** * 文件下载效果 */ @ResponseBody @RequestMapping("testResponseEntity") public ResponseEntity<byte[]> testResponseEntity(HttpSession httpSession) throws IOException { byte[] body = null; ServletContext servletContext = httpSession.getServletContext(); InputStream in = servletContext.getResourceAsStream("/files/abc.txt"); body = new byte[in.available()]; in.read(body); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("Content-Disposition","attachment;filename=abc.txt"); HttpStatus httpStatus = HttpStatus.OK; ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(body,httpHeaders,httpStatus); return responseEntity; }

读取文件内容效果

java代码:

/** * @ResponseBody 目标方法的返回值 * @RequestBody 目标方法的入参 */ @ResponseBody @RequestMapping("testHttpMessageConverter") public String testHttpMessageConverter(@RequestBody String body){ System.out.println(body); return "Hello world" + new Date(); }

jsp代码:

<form action="testHttpMessageConverter" method="post" enctype="multipart/form-data"> File:<input type="file" name="file"> Desc:<input type="text" name="desc"> <input type="submit" value="submit"> </form>

结果:

下载文件效果 选择文件读取

九、国际化

1、国际化的方式

关于国际化 1、在页面上能够根据浏览器语言设置情况对文本(不是内容),时间,数值进行本地化处理 2、可以在bean中获取国际化资源文件Locale 对应的消息 3、可以通过超链接切换Locale,而不再依赖于浏览器的语言设置情况 解决: 1、使用jstl的fmt标签 2、在bean中注入ResourceBundleMessageSource 的实例,使用其对应的getMessage方法即可 3、配置LocalResolver和LocaleChangeInterceptor

2、时间,数值进行本地化处理

1)配置国际化资源文件

<!-- 配置国际化资源文件ResourceBundleMessageSource --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> <!-- 支持UTF-8的中文 --> <property name="cacheSeconds" value="0"/> <property name="defaultEncoding" value="UTF-8"/> </bean>
2)界面
<!-- 界面i18n --> <fmt:message key="i18n.user"></fmt:message> <br><br> <a href="i18n2">i18n2</a> <!-- 界面i18n2 --> <fmt:message key="i18n.password"></fmt:message> <br><br> <a href="i18n">i18n</a>
3)界面效果

语言首选项zh-CN

显示界面1 显示界面2 语言首选项en-US 显示1

显示2

4)补充:不想通过控制器直接访问配置
<!-- spring配置文件配置 --> <!-- 不通过控制器直接访问 --> <!-- <mvc:view-controller path="/i18n" view-name="i18n"></mvc:view-controller>--> <mvc:view-controller path="/i18n2" view-name="i18n2"></mvc:view-controller>

3、通过超链接改变Locale

1)控制器
/** * 用于获取国际化资源文件对应的消息 */ @Autowired ResourceBundleMessageSource messageSource; /** * 通过超链接修改locale,国际化 */ @RequestMapping("/i18n") public String testI18n(Locale locale){ String message = messageSource.getMessage("i18n.user",null,locale); System.out.println(message); return "i18n"; }
2)配置SessionLocaleResolver
<!-- 国际化页面配置(通过超链接选择语言那种) 配置SessionLocaleResolver用于将Locale对象存储于Session中供后续使用(这里的Id只能用这个:localeResolver,否则会出问题) 第一步: --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean> <mvc:interceptors> <!-- 配置国际化页面拦截器(通过超链接选择语言那种)配置LocaleChangeInterceptor 主要用于获取请求中的locale信息,将期转为Locale对像,获取LocaleResolver对象 第二步: --> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors> <!-- SessionLocaleResolver & LocaleChangeInterceptor工作原理 LocaleChangeInterceptor 1、获取name=locale的请求参数 2、把第一步的locale请求对象参数解析为Locale对象 3、获取LocaleResolver对象 SessionLocaleResolver 4、把Locale对象设置为Session属性 5、从Session中获取Locale对象 应用程序 6、使用Locale对象 -->
3)界面超链接
<!-- 通过locale属性传递locale参数,后面会通过LocaleChangeInterceptor将其封装为Locale对象 --> <br><br> <a href="i18n?locale=zn_CH">中文</a> <br><br> <a href="i18n?locale=en_US">英文</a>
4)界面效果

待补充

十、文件上传

需要导入的包

<!-- 文件上传的jar包 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>

1、单个文件上传

1)控制器
/** * 文件上传 * 文件被封装为MultipartFile */ @RequestMapping("testFileUpload") public String testFileUpload(@RequestParam("desc") String desc, @RequestParam("file") MultipartFile file) throws IOException { System.out.println("desc:" + desc); //获取文件原始的名字 System.out.println("OriginalFilename" + file.getOriginalFilename()); //获取文件所对应的输入流 System.out.println("InputStream" + file.getInputStream()); return "success"; }
2)页面
<h4>文件上传</h4> <form action="testFileUpload" method="post" enctype="multipart/form-data"> File:<input type="file" name="file"> Desc:<input type="text" name="desc"> <input type="submit" value="submit"> </form>
3)效果

2、多个文件上传

1)控制器
/** * 多文件上传 */ @RequestMapping("testFilesUpload") public String testFilesUpload(@RequestParam("files") MultipartFile[] files) throws IOException { for (MultipartFile file:files){ System.out.println("OriginalFilename:" + file.getOriginalFilename()); System.out.println("InputStream:" + file.getInputStream()); } return "success"; }
2)页面
<h4>多个文件上传</h4> <form action="testFilesUpload" method="post" enctype="multipart/form-data"> File1:<input type="file" name="files"> File2:<input type="file" name="files"> <input type="submit" value="submit"> </form>
3)效果

十一、自定义拦截器

1、继承HandlerInterceptor

public class MyFirstInterceptor implements HandlerInterceptor { /** * 该方法在目标方法之前被调用 * 若返回true,则继续调用后续的拦截器和目标方法 * 若返回false,则不会再调用后续的拦截器和目标方法 * * 用处: * 可以考虑做权限,日志,事物等 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyFristInterceptor preHandle"); return true; } /** * 调用在目标方法之后,但在渲染视图之前 * * 用处: * 可以对请求域中的属性或者视图做出修改 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyFristInterceptor postHandle"); } /** * 渲染视图之后被调用 * * 用处: * 释放资源 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyFristInterceptor afterCompletion"); } }

2、在配置文件中注册拦截器

<mvc:interceptors> <bean id="myFirstInterceptor" class="com.test.springmvc.crud.interceptor.MyFirstInterceptor"></bean> <!-- 配置拦截器作用的路径或不作用于那个路径 --> <mvc:interceptor> <mvc:mapping path="/stus"/> <bean id="mySecondInterceptor" class="com.test.springmvc.crud.interceptor.MySecondInterceptor"></bean> </mvc:interceptor> <!-- 配置国际化页面拦截器(通过超链接选择语言那种)配置LocaleChangeInterceptor 主要用于获取请求中的locale信息,将期转为Locale对像,获取LocaleResolver对象 第二步: --> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean> </mvc:interceptors>

3、拦截器的执行顺序

1)拦截器1为true的时候

2)拦截器1为false的时候

十二、异常处理

1、ExceptionHandler注解处理异常

1)代码

/** * 1、在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数,该参数即对应发生的异常对象 * 2、@ExceptionHandler 方法的入参不能传入Map。若希望把一场信息传导到页面上,需要使用 ModelAndView 作为返回值 * 3、@ExceptionHandler 方法标记的异常优先级问题 * 精度越高优先级越高 * 例如:ArithmeticException和RuntimeException,抛出异常为ArithmeticException ,优先执行被@ExceptionHandler({ArithmeticException.class})修饰的方法 * 4、@ControllerAdvice 如果在当前Handler中找不到 @ExceptionHandler 修饰的方法来处理当前出现的异常 * ,则将会去@ControllerAdvice 标记的类中查找 @ExceptionHandler 修饰的方法来处理异常。 */ @ExceptionHandler({ArithmeticException.class}) public ModelAndView handleArithmeticException(Exception ex){ ModelAndView mv = new ModelAndView("error"); mv.addObject("exception",ex); return mv; } <body> <h4>Error</h4> ${exception} </body>

2)效果

2、ResponseStatusExceptionResolver处理异常

1)@ResponseStatus注解

修饰方法@ResponseStatus(value = HttpStatus.NOT_FOUND,reason = "测试方法@ResponseStatus注解") @RequestMapping("testResponseStatusExceptionResolver") public String testResponseStatusExceptionResolver(@RequestParam("i") Integer i){ if (i==13){ throw new MyException(); } System.out.println("testResponseStatusExceptionResolver"); return "success"; } 修饰类/** * -@ResponseStatus * value返回的状态码 * reason返回的异常原因 */ @ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "测试异常对象@ResponseStatus注释,我的异常") public class MyException extends RuntimeException{ }

2)效果

修饰方法

修饰类

3、SimpleMappingExceptionResolver处理异常

1)配置SimpleMappingExceptionResolver

<!-- 配置使用 SimpleMappingExceptionResolver 来映射异常 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!-- 配置异常的映射名 --> <property name="exceptionAttribute" value="exception"></property> <!-- 要处理的异常映射全部在其中配置 --> <property name="exceptionMappings"> <props> <!-- key 异常的全类名 prop内容 出现该异常跳转的页面 --> <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop> </props> </property> </bean>

2)运行触发异常效果

控制器尝试触发下标越界异常

@RequestMapping("testSimpleMappingExceptionResolver") public String testSimpleMappingExceptionResolver(@RequestParam("i") Integer i){ String[] vals = new String[10]; System.out.println(vals[i]); return "success"; }

注:若未设置exceptionAttribute属性则默认映射名未exception

最新回复(0)