在学习springMVC框架时,总结的一些常用的配置和易错的知识点。
1.web.xml中关于springMVC的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>springMVC_day03</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- springMVC的web.xml文件要进行3项配置:
1、由于存在客户端和服务器的传输乱码情况,因此要配置springMVC的编码过滤器CharacterEncodingFilter
2、要判断客户端发送的请求是GET(查询)、POST(新增)、PUT(修改)、和DELETE(删除)中的哪一种,
而且还带有REST风格的参数的过滤器,因此要配置一个过滤器HiddenHttpMethodFilter
3、要配置处理请求的servlet,这个servlet是springMVC封装的核心控制器dispatcherServelt
以上配置的3个类都是springMVC封装好的,我们只需要配置即可使用
-->
<!-- 1 配置编码过滤器(springMVC框架中存在缓存,所以必须将编码过滤器配置在最前面) -->
<filter>
<!-- filter-name可以自定义 -->
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!-- CharacterEncodingFilter中的变量名 -->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 2 配置判断哪种请求的过滤器 -->
<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 配置处理请求的servlet
这里我们多说一点:
3.1 如果我们这里只配置了servlet-name和servlet-class,框架默认加载WEB-INF下的一个xml文件且
该xml文件名必须为:servlet-name的值-servlet.xml。如本配置文件中servlet-name的值为springMVC,且只配置了servlet-name
和servlet-class2个标签,所以服务器启动时,默认加载WEB-INF下的名为springMVC-servlet.xml的文件
3.2 如果我们不仅配置了servlet-name和servlet-class,还配置了init-param标签属性为contextConfigLocation的子标签,此时,我们可以
将配置文件放到指定位置且文件名也可以自定义
-->
<servlet>
<!-- 可以自定义 -->
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.dispatcherServlet</servlet-class>
<!-- <init-param> -->
<!-- contextConfigLocation是dispatcherServlet的父类FrameworkServlet的属性名,不能更改 -->
<!-- <param-name>contextConfigLocation</param-name> -->
<!-- 自定义spring的配置文件存放在类路径下的自定义文件夹conf下 -->
<!-- <param-value>classpath:conf/myspringMVC.xml</param-value> -->
<!-- </init-param> -->
<!-- 加载的级别,数字越小,级别越高,服务器启动时会先加载级别高的servlet,值只能为大于0的正整数,否则将不起作用,值不能重复 -->
<!-- <load-on-startup>1</load-on-startup> -->
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- 只写一个斜线,就可以把像jsp、html等页面过滤掉 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.spring配置文件中关于springMVC的配置
注意:我这里的spring配置文件名是springMVC-servlet.xml,我选择了默认加载配置文件的方式,所以将springMVC-servlet.xml放在了动态web项目的WEB-INF目录下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- spring配置文件,要使用springMVC框架,要配置2方面:
1、开启组件的注解扫描
2、配置视图View
-->
<!-- 1、开启组件的注解扫描 -->
<context:component-scan base-package="com.atgui.controller"></context:component-scan>
<!-- 2、配置视图View -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- prefix和suffix都是InternalResourceViewResolver类的父类UrlBasedViewResolver中的属性名,不能更改 -->
<!-- 这里我在WEB-INF目录下新建了一个名为view的文件夹,自定义了请求转发的页面放置的位置 -->
<property name="prefix" value="/WEB-INF/view/"></property>
<!-- 这里我同样自定义了请求转发的页面必须是jsp文件 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
3.关于注解@RequestMapping的几点注意
我只给出了一个简单的实例方法及@RequestMapping注解,主要看懂注释文字的原理
即可
/**
* 这里注意只有当@RequestParam中的value值username在浏览器传来的数据中匹配不到时,无论require的值是啥,都会给name参数赋默认值li;
* 如果匹配到,但是前台传过来的username为空字符串,也不会给name参数赋默认值li
* 若匹配不到,但是required=false,则不会报错;若required=true,则会报错,但是require=true,defaultValue="XXX",不会报错
* 默认值只有从浏览器接收到的值为null时,才会赋值
*/
@RequestMapping(value = "/param",method = RequestMethod.POST)
public String param(@RequestParam(value = "username",required = true)String name, String password, String age) {
System.out.println("username = " + name + "; password = " + password + "; age = " + age);
return "success";
}
注意:如果@RequestMapping中的method如果不进行配置,SpringMVC默认post请求和get请求都会接收的!!!
4. 新增和修改按钮指向同一个jsp页面时,使用SpringMVC时需要注意的几个点
在实现新增和修改功能时,我们可以使用SpringMVC提供的功能将这两个按钮指向同一个页面(此处假设为edit页面)。我们主要注意以下几个方面:
<!-- 引入springMVC提供的form标签,prefix的值可以自定义,此处定义为form是为了与uri中的form保持一致 -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
注:form标签是springMVC提供的一个对基本标签form的一个封装,结合java代码可以更方便的进行数据的提取与展示。
例如:
<!-- <input type="text" name="lastName"> -->
<!-- path属性相当于name属性 -->
<form:input path="lastName"/>
<!-- <input type="radio" name="gender" value="1">男 -->
<!-- <input type="radio" name="gender" value="0">女 -->
<form:radiobuttons path="gender" items="${genders }"/>
<!-- items是要遍历的数据,使用${}获取,itemLabel是展示在给用户看的数据,itemValue是遍历的时候的value值 -->
<form:select path="department.id" items="${deps }" itemLabel="departmentName" itemValue="id"></form:select>
- 如果edit页面的
<form:form></form:form>
标签中没有设置@H_801_61@modelattribute属性,则在处理请求的controller层,我们要往request域放入一个键值对,key=“command”,value=“jsp页面中数据要绑定的对象”,如果是新增功能,放入一个空参对象;如果是修改功能,就放入要修改的那个对象即可。有小伙伴会问:key值为什么必须是"command",不能自定义吗?答案是:key值不是必须要设置成"command",如果没有在edit页面的<form:form></form:form>
标签中设置@H_801_61@modelattribute属性,则key必须设置成"command";如果设置了@H_801_61@modelattribute属性,则使用设置的属性值作为key值。我们不设置属性值时,springMVC框架默认给我们指定了@H_801_61@modelattribute属性的属性值为"command"。因此才会出现这种情况关于如何将数据放入request域,不会的小伙伴可以看这里SpringMVC中如何将数据放入request域。
注意:设置或不设置modelattribute属性,都要把它和value值放入request域中,否则,jsp页面就无法知晓要绑定哪个对象进行值的获取与绑定了,此时页面会报如下错误(使用默认属性值command报的错,自定义的属性值也会出现相似错误):
5. 关于页面静态资源不能访问导致页面加载失败的问题
使用SpringMVC之后,我启动项目,想访问一个jsp页面,此jsp页面引入了项目下的样式(可以称这个样式为静态资源),但是后台却报错了,大概的报错格式如下:
警告:No mapping found for HTTP request withURI [/XXX/XXX] in dispatcherServlet with name 'springMVC'
这是因为SpringMVC将这些链接也当成了请求,使用controller层对应的类中的方法去处理,结果发现没有对应的处理方法就会报错,导致页面加载失败!!!可是以前没有用SpringMVC的时候怎么没有遇到这种问题呢?
我们以前的部署项目时,对于css,js等引入的静态资源,Tomcat就会使用它的默认的servlet替我们处理这些静态资源,但是引入SpringMVC框架之后,默认的处理这些静态资源的servlet就不起作用了,我们需要在spring的配置文件中配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean deFinitions here -->
<!-- 配置以下2个标签用来解决页面的静态(页面中引入的css、jss等)资源加载问题
如果不配置这些标签,会出现No mapping found for HTTP request with
URI [/XXX/XXX] in dispatcherServlet with name 'springMVC'的警告
-->
<!-- 使用默认的servlet处理静态资源 -->
<mvc:default-servlet-handler/>
<!-- 开启注解驱动,SpringMVC的很多功能都要配置,否则是用不了!!! -->
<mvc:annotation-driven/>
</beans>
6. jsp页面path属性的值写错导致的问题
在使用springMVC时,从jsp页面往后台传送数据时,path属性的值必须为绑定的对象的属性名,否则会引发以下异常:
7. 使用SpringMVC进行上传与下载
7.1 上传
SpringMVC框架,对我们上传的文件进行了封装,将上传的文件File封装成了multipartfile,该类提供了很多实用的方法来处理文件的上传。减少了开发者很多工作量。
关于使用SpringMVC上传时遇到的一个小问题
在学习使用SpringMVC时,跟着视频写了一个上传图片的程序,可是怎么也不成功。报错的原因很让人纳闷。
上传的前台jsp文件和页面如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<Meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="download">下载图片</a>
<form action="upload" method="post" enctype="multipart/form-data">
头像:<input type="file" name="uploadFile" />
<!-- 头像:<input type="file" name="uploadFile" /> -->
<!-- 头像:<input type="file" name="uploadFile" /> -->
描述:<input type="text" name="desc" />
<input type="submit" value="确定上传" />
</form>
</body>
</html>
@RequestMapping(value="/upload", method=RequestMethod.POST)
public String upload_new(String desc, multipartfile uploadFile, HttpSession session) throws IOException {
//获取上传文件在jsp页面中的name属性
String prop = uploadFile.getName();
//获取上传文件的名称
String fileName = uploadFile.getoriginalFilename();
String realPath = session.getServletContext().getRealPath("upload");
String path = realPath + File.separator + fileName;
File file = new File(path);
uploadFile.transferTo(file);
System.out.println("属性:" + prop + "文件名:" + fileName + "描述:" + desc);
return "success";
}
报错如下:
我将上传到tomcat的文件夹由upload改为了photo,结果发现可以了:这里方法中的上传路径也要同步修改。
//修改
String realPath = session.getServletContext().getRealPath("photo");
暂时不明白为什么自定义的upload文件夹不行,而自定义的photo却可以实现上传功能,难道是upload在SpringMVC框架中被当成了一个请求路径之类的???问题虽解决,但是背后的原理还不知道,故做此记录,待日后解决!!!
8.在使用SpringMVC框架时,客户端的请求到底是由谁来处理?
正常情况下,客户端的请求会先经过SpringMVC的框架来进行处理,这里实用到框架提供的一个类:dispatcherServlet,这个类专门用来处理客户端的请求,如果dispatcherServlet处理不了这个请求,就会让Tomcat的默认处理请求的servlet来处理请求,但是引入SpringMVC框架后需要在xml文件中对Tomcat的处理请求的servlet进行如下配置:
<!-- 使用默认的servlet处理请求 -->
<mvc:default-servlet-handler/>
<!-- 开启注解驱动,SpringMVC的很多功能都要配置,否则是用不了!!! -->
<mvc:annotation-driven/>
如果上述配置没有配置,SpringMVC框架又处理不了客户端请求,此时前台页面会报如下错误:
后台会报如下错误:
如果上述配置正确进行了配置,但是SpringMVC框架和Tomcat都处理不了客户端请求,此时前台会报如下错误:
但是后台却没有任何错误提示。由此可以看出:Tomcat默认的处理请求的servlet是否配置,在前台的错误提示是不一样的。所以我们在遇到上述异常时,首先要检查配置文件是否配置正确。
9. Spring和SpringMVC的配置文件都扫描了同一个包,且该包下有注解会出现什么情况?
举个简单的例子:spring的配置文件如下:
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- <bean class="com.atguigu.bean.User"></bean> -->
<context:component-scan base-package="com.atguigu"></context:component-scan>
</beans>
springMVC的配置文件如下:
springMVC.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean deFinitions here -->
<!-- 开启组件的注解扫描 -->
<context:component-scan base-package="com.atguigu"></context:component-scan>
<!-- 配置视图解析 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 使用默认的servlet处理静态资源 -->
<mvc:default-servlet-handler/>
<!-- 开启注解驱动,SpringMVC的很多功能都要配置,否则是用不了!!! -->
<mvc:annotation-driven/>
</beans>
总之,无论这两个配置文件什么时候加载,它们都会扫描com.atguigu
包下的注解,并自动创建对象,这时就出现了一个类被实例化了2次,这种情况并不是我们想要看到的。如下所示:
解决上述问题最简单的办法就是:spring的配置文件只扫描除了控制层以外的的注解,而SpringMVC的配置文件只扫描控制层的注解。这样就不会出现重复扫描的问题即每个对象在容器中只存在唯一的一个!
10 .如何配置才能让tomcat容器自动的加载spring的配置文件?
10.1 加载默认路径下的spring的配置文件
如果想要tomcat服务器在启动时,加载默认路径下的spring框架的配置文件,spring框架提供了ContextLoaderListener类用来加载spring的配置文件,我们需要在web.xml中做如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!-- 使用Spring提供的加载Spring配置文件的监听器,这里默认加载WEB-INF下的名为applicationContext.xml的配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
如果WEB-INF
下没有applicationContext.xml
配置文件,启动tomcat后,会出现以下错误:
加载不到
applicationContext.xml
配置文件,我们在WEB-INF
文件夹下把applicationContext.xml
配置文件补上就可以了。
10.2 加载指定路径下的spring的指定名称的配置文件
如果想要tomcat服务器在启动时,加载指定路径下的spring框架的指定配置文件,我们需要在web.xml中做如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>springMVC_day02</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 使用Spring提供的加载Spring配置文件的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置加载spring配置文件的加载路径和要加载的文件名(这里加载类路径下的名为spring.xml的配置文件) -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
</web-app>