Spring
创建maven项目,在项目中产生的pom.xml文件中,导入spring的坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
还需要在resources中创建spring config取名applicationContext.xml
在applicationContext.xml中配置类的实现:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
在此处的id不能重复,是唯一性标识.class指向的是配置类所在的地址。通过反射机制,无参构造对象
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" scope="singleton">scope后面不配默认singleton,这里表示单例的只创建一个对象且是在创建一个容器时,创建该对象是在:ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
只要容器存在,该对象就一直存在,当容器销毁时,该对象才被销毁
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" scope="prototype">
此处表示多例的,可以创建多个对象,多个对象是在:UserSivce userSivce = app.getBean(UserSivce.class);时创建的
长时间不用,就会被gc垃圾回收机制给销毁,只要一直使用就一直活着
</bean>
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>
此处的init-method属性代表的是初始化方法,后面接的方法名,在初始化时被执行。
此处的destroy-method属性代表的是类中销毁方法,后面接的方法,在销毁时执行,需要注意的销毁太快,无法展示销毁方法的输出就执行结束了。需要手动关闭容器,才能有时间显示,代码如下:
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao uesrDao=(UserDao) app.getBean("userDao");
((ClassPathXmlApplicationContext)app).close;
Bean实例化的三种方法:
1.无参的构造方法实现(最重要的);
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource datasource=(DataSource)app.getBean("dataSource");
2.工厂静态方法实现;
<bean id="userDao" class="com.heima.dao.Factory.StaticFactory" factory-method="getUserDao"></bean>//此处加载这个配置文件时,不会直接拿工厂的无参构造方法,因为后面factory-method 指引,会直接进入这个方法里面执行此方法
//工厂静态方法执行类
//执行此方法,得到一个UserDaoImpl对象
public class SaticFactory {
public static UesrDao getUserDao(){
return new UserDaoImpl();
}
}
//测试类
public class UserDaoDemo {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) app.getBean("userDao");
uesrDao.save();
}
}
3.工厂实例方法实现;
<bean id="factory" class="com.heima.dao.Factory.DymamicFactory"></bean>//创建该工厂类的对象,拿到一个无参的工厂类对象
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>//这里表示我要获得userDao对象,需要找factory(这里写工厂的id)这个工厂的,getUserDao方法获得。
//工厂实列方法执行类(实例方法先new 对象才能调用实例方法)
//执行此方法得到一个UserDaoImpl对象
public class StaticFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
//测试类
public class UserDaoDemo {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao=(UserDao) app.getBean("userDao");
uesrDao.save();
}
}
Spring的配置文件,bean的依赖注入:
1.构造方法:
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">
<bean id="userService" class="com.heima.dao.service.UserService">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>//name后面接的是构造方法中的属性名,<constructor-arg></constructor-arg>//此配置是为有参构造方法注入值或对象;ref后面接的是要注入的对象,通过id找到此对象。
</bean>
public class UserService implements UesrDao {
private UesrDao userDao;
public UserService(UesrDao userDao) {
this.userDao = userDao;
}
public UserService() {
}
@Override
public void save() {
userDao.save();
}
}
public class UserCollection {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userService=(UesrDao) app.getBean("userService");
userService.save();
}
}
2.set方法:
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">//这是UserDaoImpl的bean配置,可以获得一个无参构造方法
<bean id="userService" class="com.heima.dao.service.UserService">//这是UserService的bean配置,可以获得一个无参构造方法
<property name="userDao" ref="userDao"></property>
</bean>//此处配在<bean>userService下面,name后面接UserService中的set方法,set方法不要set,将set后面的名,第一个小写,写在这里,setUserDao,name="userDao",这里ref是注入对象,此处是通过id找到此对象.
public class UserService implements UserDao {
private UesrDao userDao;
public void setUserDao(UserDao userDao) {//对象注入到UserDap userDao这个里面,然后赋值给userDao这个属性.
this.userDao = userDao;
}
public void save() {
userDao.save();
}
}
public class UserCollection {
public static void main(String[] args) {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");//创建容器,加载配置文件
// UserDao userService=(UserDao) app.getBean("userService");
UserService userService= app.getBean(UserService.class);//获得对象
userService.save();
}
}
引入p命名空间:
<?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:p="http://www.springframework.org/schema/p"//此处引入p命名空间
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">
<bean id="userService" class="com.heima.dao.service.UserService" p:userDao-ref="userDao">//采用p命名空间直接在后面添加属性,向set方法注入userDao对象。
</beans>
Bean的依赖注入的数据类型:
1.普通数据类型;
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">
<property name="name" value="杨明"></property>//这里是注入普通的数据类型,同样是通过set方法来实现注入,配置属性的值,这里用value来接受普通属性值
<property name="age" value="18"></property>
</bean>
public class UserDaoImpl implements UesrDao {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void save() {
System.out.println(name+"====="+age);
}
}
2.引用数据类型;
这个就是上面的对象注入,也就是引用数据类型。
3.集合数据类型;
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">
<property name="list">//注入list集合
<list>//为list集合注入值
<value>杨明</value>
<value>邹杰</value>
<value>波波</value>
</list>
</property>
<property name="map">//注入map集合
<map>
<entry key="user1" value-ref="user1"></entry>//这里key是注入值的名称,随便取名,这里的value-ref注入一个User对象,通过id找到此对象
<entry key="user2" value-ref="user2"></entry>
</map>
</property>
<property name="properties">//为properties注入内容,key表示名称
<props>
<prop key="1">p1</prop>//这里p1表示输入从内容
<prop key="2">p2</prop>
<prop key="3">p3</prop>
</props>
</property>
</bean>
<bean id="user1" class="com.heima.dao.domain.User">
<property name="name" value="杨明"></property>
<property name="addr" value="武汉"></property>
</bean>
<bean id="user2" class="com.heima.dao.domain.User">
<property name="name" value="邹杰"></property>
<property name="addr" value="北京"></property>
</bean>
public class UserDaoImpl implements UesrDao {
private List<String> list;
private Map<String, User>map;
private Properties properties;
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void save() {
System.out.println(list);
System.out.println(map);
System.out.println(properties);
System.out.println("邹杰打球");
}
}
User类,User对象
public class User {
private String name;
private String addr;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", addr='" + addr + '\'' +
'}';
}
}
Spring配置文件,import的导入其他配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="userService" class="com.heima.dao.service.UserService">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
<import resource="applicationContext-product.xml"/>//用import标签导入其他配置文件
<import resource="applicationContext-user.xml"/>
</beans>
//applicationContext-product.xml
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl">
<property name="list">
<list>
<value>杨明</value>
<value>邹杰</value>
<value>波波</value>
</list>
</property>
<property name="map">
<map>
<entry key="user1" value-ref="user1"></entry>
<entry key="user2" value-ref="user2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="1">p1</prop>
<prop key="2">p2</prop>
<prop key="3">p3</prop>
</props>
</property>
</bean>
//application-user.xml
<bean id="user1" class="com.heima.dao.domain.User">
<property name="name" value="杨明"></property>
<property name="addr" value="武汉"></property>
</bean>
<bean id="user2" class="com.heima.dao.domain.User">
<property name="name" value="邹杰"></property>
<property name="addr" value="北京"></property>
</bean>
ApplicationContext的实现类
1.ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件推荐使用这种
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
2.FileSystemXmlApplicationContext
ApplicationContext app=new FileSystemXmlApplicationContext("D:\web\spring\spring\src\main\resources\applicationContext.xml")
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
3.AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建spring容器.它用来读取注解
getBean()方法的使用
1.通过.xml文件id进行查找
UesrDao uesrDao=(UesrDao) app.getBean("userDao");
.xml中出现多个相同的class类时,因为id是唯一的,所有可以查找到
2.通过.xml文件找类.class文件查找
UserDao userDao=(UserDao) app.getBean(UserDao.class);
但是.xml文件中不能存在相同的class类配置,不然会查找失败,不知道你要找哪一个
spring配置数据源
数据源的作用
1.数据源(连接池)是提高程序性能出现的.
2.事先实例化数据源,初始化部分链接资源.
3.使用连接资源时聪数据源中获取.
4.使用完毕后将连接资源归还给数据源.
常见的数据源(连接池):DBCP,C3P9,BoneCP,Druid等
先在pom.xml中导入数据源的坐标地址
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.1</version>
</dependency>
然后手动创建数据源C3P9
@Test
public void test() throws PropertyVetoException, SQLException {
ComboPooledDataSource dataSource=new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test01?useSSL=false");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection=dataSource.getConnection();
System.out.println(connection);
connection.close();
}
改进C3P0数据源创建,用spring容器来创建数据源
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test01?useSSL=false"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
@Test
public void test1() throws SQLException, PropertyVetoException {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
spring容器加载properties
<?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,然后把里面的beans全部改成context-->
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.xsd">//复制上面http代码,也将里面的beans全部更换为context
<!--加载外部的properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driver}"></property>//value里面写${properties里面的对应的名字key}
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
</beans>
spring原始注解
在进行注解配置时,需要在applicationConext在配置组件扫描器
<!--配置组件扫描-->
<context:component-scan base-package="com.heima"></context:component-scan>
@Component:使用在类上用于实例化Bean;
//<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl"></bean>将appliactionContext中bean剪切到这里,然后@Component("userDao")就相当于这段配置
@Component("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save running.....");
}
}
@Controller:使用在web层类上用于实例化Bean;和上面@Component一样,只不过这里注解的是web层的实例化bean
@Controller("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save running.....");
}
}
@Service:使用在service层类上用于实例化Bean;
@Service("userService")
public class UserServiceImpl implements UserSivce {
private UserDao userDao;
//<property name="userDao" ref="userDao"></property>
@Autowired
@Qualifier("userDao")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
@Repository:使用在dao层用于实例化Bean;
@Autowired:使用在字段上用于根据类型依赖注入;
@Service("userService")
public class UserServiceImpl implements UserSivce {
@Autowired
private UserDao userDao;//这里会按照数据类型从spring容器中进行匹配,找到了,就直接赋值属性了。注入了。(前提是spring中这个类型的数据只能有一个,不然就会不知道注入哪个了?)
@Override
public void save() {
userDao.save();
}
}
@Qualifier:结合@Autowired一起使用用于根据名称进行依赖注入;(必须与@Autowired一起使用,@Qualifier是按照id进行注入的)
// <bean id="userService" class="com.heima.service.impl.UserServiceImpl">
// </bean>
@Component("userService")//组件的意思
public class UserServiceImpl implements UserSivce {
@Autowired
@Qualifier("userDao")//这里俩个注解相对于上面<property name="userDao" ref="userDao"></property>进行注入,这里@Qualifier里面写要注入的id。注入到下面这个方法里面。
private UserDao userDao;
//<property name="userDao" ref="userDao"></property>
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}//这里用注解进行配置的话,这里的set方法可以删除,上面的注解会自动识别类型进行导入属性。
@Override
public void save() {
userDao.save();
}
}
@Resource:相对于@Autowird+@Qualifier,按照名称进行注入;
@Resource(name="userDao")//这里相当与@Autowird+@Qualifier,name=这里填写id值
private UserDao userDao;
}
这里注意,如果用Resource注解时报错,这是因为没有导入tomcat的包,tomcat里面默认继承了这个包,只要在pom.xml增加这个包的依赖,问题就解决了,代码如下
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
@Value:注入普通属性;
@Value("${driver}")
private String driver;//在将jdbc.properties引入spring容器中之后,就可以直接用@Value("${driver}")进行属性注入,spring中不需要在写<property name="driverClass" value="${driver}"></property>进行注入了。
@Scope:标注Bean的作用范围;
@Scope("prototype")相当与
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" scope="prototype">中的scope="prototype"配置的多个对象
@Scope("singleton")相当于
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" scope="singleton">中的scope="singleton"配置的单个对象
@PostConstruct:使用在方法上标注该方法是Bean的初始化方法;
@PostConstruct
public void init(){
System.out.println("初始化执行了");
}//相当于<bean>中注入的init-method方法
@PreDestroy:使用在方法上标注该方法是Bean的销毁方法;
@PreDestroy
public void destroy(){
System.out.println("方法销毁了");
}//相当于<bean>中注入的destory-method方法//这里需要在测试类中手动关闭spring容器,app.close
Spring注解开发
Spring新注解
@Configguration用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
@Configuration//该配置表示将该类设为核心配置类
@ComponentScan用于指定spring在初始化容器时要扫描的包,作用和在spring的xml配置文件中的<context:component-scan base-package=‘com.itheima’/>一样
@ComponentScan("com.itheima")//相当于组件扫描这个包下的注解。
@Bean使用在方法上,标注将该方法的返回值存储到Spring容器中
@Bean("dataSource")//spring会将当前方法的放回值以指定名称存储到spring容器中
@PropertySource用于加载.properties文件中的配置
@PropertySource("classpath:jdbc.properties")// <context:property-placeholder location="classpath:jdbc.properties"/>
@import用于导入其他配置类
@Import({DataSourceConfig.class})//将其他配置类文件导入
结合这几个注解的联合代码
核心配置类
//该配置表示将该类设为核心配置类
@Configuration
@ComponentScan("com.heima")// <context:property-placeholder location="classpath:jdbc.properties"/>
@Import({DataSourceConfig.class})//引入其他配置文件类
public class SpringConfig {
}
@PropertySource("classpath:jdbc.properties")// <context:property-placeholder location="classpath:jdbc.properties"/>
public class DataSourceConfig {
@Value("${driver}")
private String driver;
@Value("${url}")
private String jdbcurl;
@Value("${user}")
private String user;
@Value("${password}")
private String password;
@Bean("dataSource")//spring会将当前方法的放回值以指定名称存储到spring容器中
public DataSource test() throws PropertyVetoException, SQLException {
ComboPooledDataSource dataSource=new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(jdbcurl);
dataSource.setUser(user);
dataSource.setPassword(password);
return dataSource;
}
}
test测试类
public class UserController {
public static void main(String[] args) {
ApplicationContext app=new AnnotationConfigApplicationContext(SpringConfig.class);//这个时候applicationContext.xml配置文件就没用了,用这个方法引入核心配置类创建对象容器,全注解设计,这个方法括号里面写核心配置类名字加.class
UserSivce userSivce = app.getBean(UserSivce.class);
userSivce.save();
}
}
Spring集成Junit步骤
1.导入spring集成Junit的坐标
在pom.xml文件中配置
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
2.使用@Runwith注解替换原来的运行期
@RunWith(SpringJUnit4ClassRunner.class)//这里RunWith注解代表的是谁来跑这个测试类,这里是用spring提供的内核来跑
3.使用@ContextConfigguration指定配置文件或配置类
@ContextConfiguration("classpath:applicationContext.xml")//指定配置文件位置
加入用的全注解方式,这里测试就指定核心配置文件的.class
@ContextConfiguration(classes={SpringConfig.class})
4.使用@Autowired注入需要测试的对象
@Autowired
private UserSivce userSivce;
@Autowired
private DataSource dataSource;
//进行引用属性注入值
5.创建测试方法进行测试
综合(.xml文件进行spring容器配置的方法):
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunitTest {
@Autowired
private UserSivce userSivce;
@Autowired
private DataSource dataSource;
@Test
public void test01() throws SQLException {
userSivce.save();
System.out.println(dataSource.getConnection());
}
}
(全注解的方式)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class SpringJunitTest {
@Autowired
private UserSivce userSivce;
@Autowired
private DataSource dataSource;
@Test
public void test01() throws SQLException {
userSivce.save();
System.out.println(dataSource.getConnection());
}
}
Spring集成web环境的三层架构,项目构建:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MstErtLp-1666180627527)(Spring学习文档.assets/image-20221015155616821.png)]
UserDao接口:
package com.heima.dao;
public interface UserDao {
public void save();
}
UserService接口:
package com.heima.service;
public interface UserService {
public void save();
}
UserDaoImpl类实现UserDao接口:
package com.heima.dao.impl;
import com.heima.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save running......");
}
}
UserService类实现UserService接口:
package com.heima.service.impl;
import com.heima.dao.UserDao;
import com.heima.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void save(){
userDao.save();
}
}
web层+下的,UserServlect
package com.heima.web;
import com.heima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=app.getBean(UserService.class);
userService.save();
}
}
web.xml中配置:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.heima.web.UserServlect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
<!-- <display-name>Archetype Created Web Application</display-name>-->
</web-app>
pom下,我导入的全部jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring2</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>test</scope>
</dependency>
<!--加入servlet依赖(servlet的jar)-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<!--配置Dao-->
<bean id="userDao" class="com.heima.dao.impl.UserDaoImpl"></bean>
<!--配置service-->
<bean id="userService" class="com.heima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
将ApplicationContext app=new ClassPathXmlApplicationContext(“applicationContext.xml”);存到ServletContext域中,设置一个监听器来实现存入,在初始化的时候进行加载:
package com.heima.web;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextLoaderListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent){
ServletContext servletContext = servletContextEvent.getServletContext();
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
servletContext.setAttribute("app",app);
System.out.println("spring容器创建完毕");
}
}
进行取出app对象操作:
package com.heima.web;
import com.heima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
UserService userService=app.getBean(UserService.class);
userService.save();
}
}
web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<listener>
<listener-class>com.heima.web.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.heima.web.UserServlect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
<!-- <display-name>Archetype Created Web Application</display-name>-->
</web-app>
改良代码实现分离,降低耦合性,实现开闭原则:
web.xml:设置一个全局初始化参数,将xml文件存入其中
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!--全局初始化参数 -->
<context-param>
<param-name>appxml</param-name>
<param-value>applicationContext.xml</param-value>
</context-param>
<!--设置监听器-->
<listener>
<listener-class>com.heima.web.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.heima.web.UserServlect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
<!-- <display-name>Archetype Created Web Application</display-name>-->
</web-app>
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextLoaderListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent){
ServletContext servletContext = servletContextEvent.getServletContext();//获取servletContext域
String appxml = servletContext.getInitParameter("appxml");//从域中取出全局初始化参数
ApplicationContext app=new ClassPathXmlApplicationContext(appxml);
servletContext.setAttribute("app",app);
System.out.println("spring容器创建完毕");
}
}
//该类用于接收servletContext对象,返回从servletContext域取出的applicationContext.xml,该类的实现,有利于无论你怎么修改spring容器的配置文件,都不用修改底层代码
package com.heima.web;
import org.springframework.context.ApplicationContext;
import javax.servlet.ServletContextUtiles;
public class WebApplicationContext {
public static ApplicationContext applicationContext(ServletContext servletContext){
return (ApplicationContext) servletContext.getAttribute("app");
}
}
该类用于实现
package com.heima.web;
import com.heima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
ApplicationContext app = WebApplicationContext.applicationContext(servletContext);
UserService userService=app.getBean(UserService.class);
userService.save();
}
}
当然了,spring为我们提供了监听器,所有我们只需要进行俩个操作就能完成以上工作:
1.在web.xml中配置ContextLoaderListener监听器(首先要在pom.xml中导入导入spring-web坐标)
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
web:
全局初始化参数:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
spring提供的监听器:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
2.使用WebApplicationContext获得应用上下文对象ApplicationContext
package com.heima.web;
import com.heima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UserServlect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
//ApplicationContext app = WebApplicationContext.applicationContext(servletContext);
WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService=app.getBean(UserService.class);
userService.save();
}
}
Spring MVC
SpringMVC开发步骤:
1.导入SpringMVC相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
2.配置SpringMVC核心控制器DispathcerServlet
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3.创建Controller类和视图页面
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
}
4.使用注解配置Controller类中业务方法的映射地址
@RequestMapping("/quick")
public String save(){
System.out.println("Controller running....");
return "success.jsp";
}
5.配置SpringMVC核心文件spring-mvc.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.xsd">//
<!--组件扫描-->
<context:component-scan base-package="com.heima.controller"></context:component-scan>
</beans>
SpringMVC注解解析
@Controller
相当于在xml中配置了本类的bean来创建对象
@RequestMapping
作用:用于建立请求URL和处理请求方法之间的对应关系(也可以写着类上,只不过访问方法的路径,需要拼接上类上的RequestMapping里面的路径)
位置:
1.类上,请求URL的第一级访问目录,此处不写的话,就相当于应用的根目录
2.方法上,请求URL的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径属性:
1.value:用于指定请求的URL。它和path属性的作用是一样的
@RequestMapping(value = "/quick")
2.method:用于指定请求的URL。它和path属性的作用是一样的
@RequestMapping(value = "/quick",method = RequestMethod.GET)//这里的方式,要用枚举来实现
3.params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
例如:
1.params={“accountName”},表示请求参数必须有accountName
2.params={“moeny!100”},表示请求参数中money不能是100
@RequestMapping(value = "/quick",method = RequestMethod.GET,params = {"username"})
访问时后面必须接username=xxx什么的
http://localhost:8080/untitled1/quick?username=xxx
组件扫描器里面的配置
<context:component-scan base-package="com.heima.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
//表示扫描com.heima.controller下的Controller注解
<context:component-scan base-package="com.heima.controller">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
//表示扫描com.heima.controller下的Controller注解
视图解析器:
有几个重要的属性:
1.forward:
return "forward:/success.jsp";
//这里相当于转发
//请求时连接: http://localhost:8080/untitled1/quick?username=xxx
2.redirect
return "redirect:/success.jsp";
//这里相当于重定向
//请求时连接:http://localhost:8080/untitled1/success.jsp
配置内部资源视图解析器
<!--配置内部资源视图解析器-->
<bean id="view" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀/jsp/-->
<property name="prefix" value="/jsp/"></property>
<!--后缀.jsp-->
<property name="suffix" value=".jsp"></property>
</bean>
//我的.jsp在webapp项目下有给jsp目录配置这个之后在类中就只需写:
return "success";
这里不配置就需这样写:return "/jsp/success.jsp";
注意.jsp目录只能写着webapp下面,不能写在WEB-INF下面,知会对视图进行操作.
SpringMVC响应
1.1返回字符串形式,上面的配置内部资源视图解析器就是该方法案例。
1.2返回ModelAndView对象
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/quick1")
public ModelAndView save1(){
ModelAndView modelAndView=new ModelAndView();
//设置数据模型
modelAndView.addObject("username","邹杰");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
在浏览器上输入请求:http://localhost:8080/untitled1/user/quick1
此视图存入的数据在.jsp进行取出:
<body>
<h1>Success! ${username}</h1>
</body>
1.2.1不自己new对象,让springMVC为我提供一个ModelAndView对象:
@RequestMapping(value = "/quick2")
//在方法里面写参数,springmvc进行识别,然后提供一个对象
public ModelAndView save2(ModelAndView modelAndView){
//设置数据模型
modelAndView.addObject("username","邹杰");
//设置视图名称
modelAndView.setViewName("success");
return modelAndView;
}
1.2.2仅仅传入数据模型,将数据存储,返回字符串:
@RequestMapping(value = "/quick3")
//同上所述一样,springmvc给我们提供的一个model对象:
public String save3(Model model){
//设置数据模型
model.addAttribute("username","儿科");
return "success";
}
1.2.3用web中的request进行数据传入(在框架中不建议用这种方法,在框架中用框架的方法比较好):
@RequestMapping(value = "/quick5")
public String save5(HttpServletRequest request){
//设置数据模型
request.setAttribute("username","路飞");
return "success";
}
1.3回写数据
1.3.1
@RequestMapping("/quick6")//运用web中的response响应数据到页面展示
public void save6(HttpServletResponse response) throws IOException {
response.getWriter().print("helloworld");
}
1.3.2
不用web里面的response,用注解@ResponseBody来告诉SpringMVC框架,不进行视图跳转,直接进行数据响应
@RequestMapping("/quick7")
@ResponseBody
public String save7() throws IOException {
return "helloworld";
}
1.3.3
使用json将字符串转化为json格式的字符串返回
@RequestMapping("/quick8")
@ResponseBody//这里还是要加这个注解,不然springmvc会把这个当成视图进行跳转
public String save8() throws IOException {
return "{\"username\":\"yangming\",\"age\":\"18\"}";
}
使用json的转换工具将对象转换成json格式的字符串在返回
1.首先要配置依赖,在pom.xml配置以下依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
2.然后创建一个user类,用json工具把这个类转换成json格式的字符串
@RequestMapping("/quick9")
@ResponseBody
public String save9() throws JsonProcessingException {
User user=new User();
user.setName("yangming");
user.setAge(18);
ObjectMapper om=new ObjectMapper();
String json = om.writeValueAsString(user);
return json;
}
1.3.4返回对象或集合(转化为json格式字符串)
//SpringMVC内部帮忙转化为json格式字符串
//sping-mvc.xml配置如下:
<!--配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>//注入一个json的转换器
</list>
</property>
</bean>
@RequestMapping("/quick10")
@ResponseBody
public User save10() throws JsonProcessingException {
User user=new User();
user.setName("lisi");
user.setAge(28);
return user;//此处返回的user对象会被配置的处理器映射器转化为json字符串
}
以上改进之后不需要写处理器映射器的配置
直接配置mvc的注解驱动即可:
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"//这句注册mvc命名空间
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.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">//配置命名空间地址
<!--mvc的注解驱动-->
<mvc:annotation-driven/>//配置中填写我添加的几串代码即可
SpringMVC获得请求数据
2.1获得请求参数
1.获取简单参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配(springmvc帮你封装);
@RequestMapping("/quick11")
@ResponseBody
public void save11(String username,int age) throws JsonProcessingException {//Spingmvc自动帮忙获取这俩个参数
System.out.println(username);
System.out.println(age);
}
在浏览器上这么发布请求:http://localhost:8080/untitled1/user/quick11?name=zx&age=18,如果name于age没有对应会是空值,属性名必须一致,如果后面没有写属性则程序报错。
2.获得POJO类型参数
Controller中的业务方法的POJO参数的属性名于请求参数的name一致,参数值会自动映射匹配。
@RequestMapping("/quick12")
@ResponseBody
public void save12(User user) throws JsonProcessingException {
System.out.println(user);
}
在浏览器上这么发布请求:http://localhost:8080/untitled1/user/quick12?name=zx&age=18如果name于age没有对应会是空值,属性名必须一致,如果后面没有写属性则程序也默认user对象为null。
3.获取数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。
@RequestMapping("/quick13")
@ResponseBody
public void save13(String[] strs) throws JsonProcessingException {
System.out.println(Arrays.asList(strs));
}
在浏览器上这么发布请求:http://localhost:8080/untitled1/user/quick13?strs=aaa&strs=bbb&strs=ccc
4.1.获得集合类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以
1.首先创建一个集合类,用来封装user对象
public class Vo {
private List<User> userList;
public Vo() {
}
set,get,toString方法都要有
}
2.因为直接在浏览器上面写,太过于复杂,所有创建一个from表单进行请求:
<body>
<form action="${pageContext.request.contextPath}/user/quick14">
<!--表面第一个user对象封装到userList集合里面-->
<input type="text" name="userList[0].name"><br>
<input type="text" name="userList[0].age"><br>
<!--表面第二个user对象封装到userList集合里面-->
<input type="text" name="userList[1].name"><br>
<input type="text" name="userList[1].age"><br>
<input type="submit" name="提交">
</form>
</body>
3.在UserController中编写方法
@RequestMapping("/quick14")
@ResponseBody
public void save14(Vo vo) throws JsonProcessingException {
System.out.println(vo);
}
4.2获得集合类型参数
当使用ajax提交时,可以指定contentType为json形式,那么在方法参数位置使用@RequesuBod可以直接接收集合数据而无需使用POJO进行包装。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.6.1.min.js"></script>
<script>
var userList=new Array();
userList.push({name:"zhangsan",age:18});
userList.push({name:"lisi",age:28});
$.ajax({
type:"GET",
url:"${pageContext.request.contextPath}/user/quick15",
data:JSON.stringify(userList),
contentType:"application/json;charset=utf-8"
});
</script>
</head>
<body>
</body>
</html>
spring-mvc.xml配置:
<!--开放资源访问-->这里的mapping代表地址,location代表哪个目录下的资源
<mvc:resources mapping="/js/**" location="/js/"/>
这里还可以写
<!--<mvc:default-servlet-handler/>-->来代替上面的配置
这里的意思是如果spring容器找到该资源,将资源交给tomcat,让tomcat来帮忙找资源。
@RequestMapping("/quick15")
@ResponseBody
public void save15(@RequestBody List<User> userList) throws JsonProcessingException {
System.out.println(userList);
}
SpringMVC配置全局乱码过滤器
<!--配置全局过滤器filer-->
<filter>
<filter-name>CharacterEncodingFiter</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>CharacterEncodingFiter</filter-name>
<url-pattern>/*</url-pattern>//表示此项目下所有路径
SpringMVC获得请求数据
参数绑定注解@requestParam
当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定
@RequestMapping("/quick16")
@ResponseBody
public void save16(@RequestParam(value = "name") String username) throws JsonProcessingException {
System.out.println(username);
}
发送请求链接:http://localhost:8080/untitled1/user/quick16?name=zhangsan
@RequestParam有以三个属性:
1.value:与请求参数名称
2.required:此在指定的请求参数是否必须包括,默认是true,提交时如果没有此参数则报错,为false,则控制台不报错,输出null
3.defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
@RequestMapping("/quick16")
@ResponseBody
public void save16(@RequestParam(value = "name",required = false,defaultValue = "邹杰") String username) throws JsonProcessingException {
System.out.println(username);
}
5.1
获得Restful风格的参数
Restful风格的请求是使用"url+请求方式"表示一次请求目的的,HTTP协议里面四个表示操作方式的动词如下:
GET:用于获取资源
POST:用于新建资源
PUT:用于更新资源
DELETE:用于删除资源
@使用PathVariable注解进行占位符的匹配获取工作
@RequestMapping("/quick17/{username}")
@ResponseBody
public void save17(@PathVariable("username") String username) throws JsonProcessingException {
System.out.println(username);
}
请求链接:http://localhost:8080/untitled1/user/quick17/zhanghan
5.2
自定义类型转换器
开发步骤:
1.定义转换器类实现Converter
2.在配置文件中声明转换器
3.在中引用转换器
自定义类实现Converter:
public class DateConverter implements Converter<String,Date> {
@Override
public Date convert(String dateStr) {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
Date date=null;
try {
date=format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
在配置文件中声明转发器:
<!--mvc的注解驱动-->
<mvc:annotation-driven conversion-service="conversionService2"/>
<!--声明转换器-->
<bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.heima.converter.DateConverter"></bean>
</list>
</property>
</bean>
//在<annotation-driven>中引用转换器:
@RequestMapping("/quick18")
@ResponseBody
public void save18(Date date) throws JsonProcessingException {
System.out.println(date);
}
获得Servlet相关API
HttpServletRequest
HtttpServletReponse
HttpSession
//由SpringMvc来调用,然后springmvc为参数传入参数值
@RequestMapping("/quick19")
public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession httpSession) throws JsonProcessingException {
System.out.println(request);
System.out.println(response);
System.out.println(httpSession);
}
获得请求头:
@RequestHeader
使用@RequestHeader可以获得请求头信息,相当于web阶段学习的request.getHeader(name)
@RequestHeader注解的属性如下:
1.value:请求头的名称
2.required:是否必须携带此请求头
@RequestMapping("/quick20")
@ResponseBody
public void save20(@RequestHeader(name = "Cookie",required = false) String s ) throws JsonProcessingException {
System.out.println(s);
}
name的名称必须与请求头中需要取得的数据的名称一致
@CookieValue
1.value:请求头的名称
2.required:是否必须携带此请求头
@RequestMapping("/quick21")
@ResponseBody
public void save21(@CookieValue(name = "JSESSIONID",required = false) String s) throws JsonProcessingException {
System.out.println(s);
}
//这个注解是更深层次的获取Cookie的值
name必须是请求头Cookie中JSESSIONID,获取的值是JSESSIONID
等号后面的值
注意:虽然这里没有跳转到别的页面,但是必须也要写,不然默认把/quick21路径加上spring-mvc.xml前缀和后缀配置
但是如果你写的类中,没有用到spring框架的注解等一系列spring中的东西,它就默认把该服务默认为web服务,所以不配置@SpringBody也没有关系。
5.3
文件上传
文件上传客户端三要素
1.表单项type=“file”
2.表单的提交方式是post
3.表单的enctype属性是多部分表单形式,及enctype=“multipart/form-data”
<body>
<form action="${pageContext.request.contextPath}/user/quick22" method="post" enctype="multipart/form-data">
名称<input type="text" name="username"><br>
文件<input type="file" name="upload"><br>
<input type="submit" name="提交">
</form>
</body>
当form表单修改为多部分表单时,request.getParameter()将失效
enctype="application/x-www-form-urlencoder"时,form表单的正文内容格式是:
key=value&key=value&key=value
当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:
5.4单文件上传步骤
1.导入fileupload和io坐标
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.配置文件上传解析器
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="50000"></property>
</bean>
3.编写文件上传代码
@RequestMapping("/quick22")
@ResponseBody
public void save22(String username, MultipartFile upload) throws JsonProcessingException {
System.out.println(username);
System.out.println(upload);
}//注意这里的俩个参数名称,必须和jsp中form表单提交的俩个名称一致,不然拿不到数据
4.将文件存到本服务器端的磁盘上
@RequestMapping("/quick22")
@ResponseBody
public void save22(String username, MultipartFile upload) throws IOException {
// System.out.println(username);
// System.out.println(upload);
//获取文件名
String originalFilename = upload.getOriginalFilename();
System.out.println(originalFilename);
//存到本服务器的磁盘中
upload.transferTo(new File("E:\\upload\\"+originalFilename));
}
5.多文件上传:
<body>
<form action="${pageContext.request.contextPath}/user/quick23" method="post" enctype="multipart/form-data">
名称<input type="text" name="username"><br>
文件<input type="file" name="upload"><br>
文件<input type="file" name="upload"><br>
<input type="submit" name="提交">
</form>
</body>
@RequestMapping("/quick23")
@ResponseBody
public void save23(String username, MultipartFile[] upload) throws IOException {
for (MultipartFile multipartFile : upload) {
String originalFilename = multipartFile.getOriginalFilename();
System.out.println(originalFilename);
multipartFile.transferTo(new File("E:\\upload\\"+originalFilename));
}
}