Spring框架开发下配置文件的关系及内容
01. applicationContext.xml (POJO等内容的登记处理,名字随意)
* 在文件中,主要配置为 组件扫描;(注意 context 命名域的引用)
<context:component-scan base-package="基础包路径"/>
* 如果不使用注解模式开发,可以文件中对pojo对象进行配置
02. spring-mvc.xml (专门用来配置springmvc的配置文件,名字随意, 当然,也可以直接将配置内容配置到 applicationContext.xml 中)
* 在文件中,主要配置为 组件扫描; (注意 context 命名域的引用),主要是扫描 Controller 前端控制器的目录, 如: club.wuyu.controller
<context:component-scan base-package="基础包路径"/>
* 配置内部资源视图解析器
一般用于配置 spring mvc 的前缀,后缀等内容;
配置好以后,可以在控制器中,直接返回对应的路由名称
* 注解驱动及静态资源放行 (若涉及到POJO对象的直接传参及返回,注意对jackson相关包的引用)
03. web.xml
* 配置web服务加载监听器及监听器所需要的配置参数
> 主要在于对 ApplicationContext 的一次加载,多次使用;避免每次web请求都去加载这个内容;
> 监听器需要的配置文件(即: applicationContext.xml ) ,直接通过 web服务上下文参数传入
> 对于初始化参数的读取,如下:
* 常规 servlet 映射配置 ( UserServlet 继承 HttpServlet )
* Spring mvc 的前端控制器配置
* 字符编码配置(解决乱码)
04. Controller 控制器中,页面跳转的配置
> 直接返回字符串
> 返回 modelandview
(模式1: 函数内部创建 ModelAndView)
(模式2: 在参数中定义 modelandview, 由 SpringMVC框架注入实现 modelandview 的创建)
(模式 3: 将模型与视图分离)
(模式4: 原生方式)
05. Controller中返回数据
> 直接返回字符串
也可直接 return 信息,但需要配置 @ResponseBody
将对象转化为JSON进行返回
>> 需要先导入jackson的坐标
>>基于 SpringMVC的对象转JSON,就不需要手动将对象转成JSON了
* Spring-MVC.xml 中配置映射器
* 返回数据时,可以直接返回对象
> 直接返回对象
** 在上面的例程中,通过配置映射器,实现了对象到 json 的转换,但配置有些复杂;
>> 在 Sping-MVC.xml 中进行 mvc的注解驱动配置,可快速实现上述功能及其它更多注解辅助功能;
06.请求参数的获取
> 基本数据类型的参数
** 确保传入参数的名称与函数的参数名称一致,spring-mvc将自动完成封装;
>> http://localhost/mv7?username=zhangsan&age=18
> POJO类型的参数
** 参数传递时,直接传递POJO对象,spring-mvc 会依据传入的参数,自动封装pojo对象
>> http://localhost/mv8?username=zhangsan&age=18
//直接传参POJO对象
> 数组类型的参数
** 参数传递时,参数名与函数的参数名一致,当多个参数的参数名一致时,将自动封装为一个数组
http://localhost/mv9?hobbys=study&hobbys=playgame&hobbys=fly
> 集合类型的参数
** 集合参数的获取,无法直接传参数的方式解决,需要将集合参数包装到一个pojo对象中才可以
** 集合的获取方式2
>> 当 使用 ajax 提交数据时,可以指定 contentType 为 json 形式,在方法参数位置使用 @RequestBody 可以直接接收集合数据而无需使用POJO进行包装;
>>>-----------------------------------------------------------------------<<<
07.关于字符编码问题 (特别重要,特别重要)
>> a. 网络上关于 springmvc中编码的解决配置,基本类似,无外乎在 web.xml 中配置一下过滤器 (网上查了好多,基本都是这样子的,但实际使用响应时,依然是乱码,字符集为:charset=ISO-8859-1)
>>> 关于 forceEncoding 参数的理解
>>源码跟踪
* 控制器及请求响应情况:
* 代码追踪
/> 请求: http://localhost/check1?username=中国
/> 首先进行过滤器进行处理, 请求编码,响应编码,都修改成了设置的值 utf-8
/> 进入 控制器,进行业务处理, 数据正常,并配置响应内容
/> 处理完控制器内容,继续处理后续内容
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs); //处理请求,
org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
return this.doInvoke(args);
org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
return this.getBridgedMethod().invoke(this.getBean(), args); // doInvoke中的这一句,就是调用控制器的代码
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest); //处理结果
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor#handleReturnValue
** 在函数中,对请求参数,再次做了一次装饰封装;
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor#writeWithMessageConverters()
converter.write(body, selectedMediaType, outputMessage); /*此时,outputMessage.getServletResponse 原响应对象编码依然为 utf-8*/
org.springframework.http.converter.AbstractHttpMessageConverter#write
org.springframework.http.converter.AbstractHttpMessageConverter#addDefaultHeaders
this.writeInternal(t, outputMessage); //通过调用本函数,向客户端响应
org.springframework.http.converter.AbstractHttpMessageConverter#writeInternal
------------------------------------------------------
字符编码常规处理 (web.xml):
1 <!--web.xml中配置过滤器--> 2 <filter> 3 <filter-name>encodingFilter</filter-name> 4 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 5 <init-param> 6 <param-name>encoding</param-name> 7 <param-value>utf-8</param-value> 8 </init-param> 9 <init-param> 10 <param-name>forceEncoding</param-name> 11 <param-value>true</param-value> 12 </init-param> 13 </filter> 14 <filter-mapping> 15 <filter-name>encodingFilter</filter-name> 16 <url-pattern>/*</url-pattern> 17 </filter-mapping>
若无法解决,可配置 tomcat的配置文件 (conf/server.xml)
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
若上述配置依然出现乱码,再配置 spring-mvc.xml 配置文件
1 <mvc:annotation-driven> 2 <mvc:message-converters> 3 <bean class="org.springframework.http.converter.StringHttpMessageConverter"> 4 <constructor-arg value="utf-8"/> 5 </bean> 6 </mvc:message-converters> 7 </mvc:annotation-driven>
08.在路由名称和函数名称一样时,提示循环视图的异常报告
>> 处理方式: 将类的 @Controller 注解,调整为 @RestController
09. @RequestParam 注解的使用
10. 关于 restful 风格的理解
11. 关于请求头和cookie值的提取
12.文件上传
>> 文件上传相关坐标导入
>> spring-mvc.xml 中配置文件上传解析器
>> 文件上传代码
>>编写前端上传代码 (注意参数名称与前端代码中的name要一致)
>> 多文件上传
>> Demo代码
>>> 坐标引用
1 <dependency> 2 <groupId>commons-fileupload</groupId> 3 <artifactId>commons-fileupload</artifactId> 4 <version>1.4</version> 5 </dependency> 6 <dependency> 7 <groupId>commons-io</groupId> 8 <artifactId>commons-io</artifactId> 9 <version>2.11.0</version> 10 </dependency>
>>> 文件上传解析器
1 <bean id="multipartResolver" 2 class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 3 <property name="defaultEncoding" value="utf-8"/> 4 <property name="maxUploadSize" value="500000"/> 5 <property name="maxUploadSizePerFile" value="500000"/> 6 </bean>
>>> 上传控制器代码
1 @RequestMapping("/t8") 2 @ResponseBody 3 public String test08(String name, MultipartFile[] files) { 4 5 System.out.println("上传者:" + name); 6 try { 7 for (MultipartFile file : files) { 8 String filename = file.getOriginalFilename(); 9 file.transferTo(new File("D:\\upload\\" + filename)); 10 } 11 return "文件上传成功"; 12 } catch (IOException e) { 13 e.printStackTrace(); 14 return "上传失败:"+e.getMessage(); 15 } 16 }
>>> JSP代码
<form method="post" action="${pageContext.request.contextPath}/t8" enctype="multipart/form-data"> 上传人:<input type="text" name="name"><br/> 文件1:<input type="file" name="files"><br/> 文件2:<input type="file" name="files"><br/> 文件3:<input type="file" name="files"><br/> <input type="submit" value="上传"> </form>