spring+springmvc-总结

一、spring

轻量级框架
aop(面向切面编程,切面修改源代码)、ioc(控制反转,创建组件)
一站式框架

web层:springMVC
service层:spring的ioc
dao层:spring的jdbcTemplate

官方建议配置文件(名称 位置没要求 ): applicationContext.xml

​ -->xiaokai

1.bean实例化方式


  • 实体类的无参数构造创建(重点

    <bean id="user" class="cn.itcast.ioc.User" scope="prototype">bean>
    如果只有有参构造,没有无参构造,会报如下错:No default constructor found
    
  • 静态工厂创建(工厂方法是static)

    创建静态的方法,返回类对象

    public class Bean2Factory {
    	//静态的方法,返回Bean2对象
    	public static Bean2 getBean2(){
    		return new Bean2();
    	}
    }
    

    xml中配置

    
    
    <bean id="bean2" class="cn.itcast.bean.Bean2Factory" factory-method="getBean2">bean>
    
  • 实例工厂创建(方法不是静态的)

    创建不是静态的方法,返回类对象

    public class Bean3Factory {
    	public Bean3 getBean3() {
    		return new Bean3();
    	}
    }
    

    xml配置

    
    
    <bean id="bean3Factory" class="cn.itcast.bean.Bean3Factory">bean>
    <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3">bean>
    
  • Bean标签常用属性

    (1)id属性:起名称,id属性值名称任意命名
    	- id属性值,不能包含特殊符号
    	- 根据id值得到配置对象
    (2)class属性:创建对象所在类的全路径
    (3)scope属性
    	- singleton:默认值,单例 
    	- prototype:多例
    	- request:创建对象把对象放到request域里面
    	- session:创建对象把对象放到session域里面
    	- globalSession:创建对象把对象放到globalSession里面
    

2.属性注入(xml)


  1. 简单属性
  • 有参构造注入

    //代码
    public class PropertyDemo1 {
      private String username;
      public PropertyDemo1(String username) {
        this.username = username;
      }
      public void test1() {
        System.out.println("demo1.........."+username);
      }
    }
    
    
    <bean id="demo" class="cn.itcast.property.PropertyDemo1"> -->
      
      <constructor-arg name="username" value="小王小马">constructor-arg>
    bean>
    
  • set方法注入(重点

    private String bookname;
    //set方法
    public void setBookname(String bookname) {
      this.bookname = bookname;
    }
    
    方式一:	
    (**重点**)
    <bean id="book" class="cn.itcast.property.Book"> -->
      
      <property name="bookname" value="易筋经">property>
    bean>
    
    方式二:
    beans标签内加入属性:xmlns:p="http://www.springframework.org/schema/p"
    beans标签内加入子标签:
    <bean id="book" class="cn.itcast.property.Book" p:bookname="易筋经">bean>
    
  1. 复杂属性
  • 第一步 创建实体类,定义成员变量数组arrs,List数组list,Map集合map,Properties类型properties;创建这几个成员变量的set方法

  • 第二步 xml配置

    
    <bean id="person" class="cn.itcast.property.Person">
        
        <property name="arrs">
          <list>
            <value>小王value>
            <value>小马value>
            <value>小宋value>
          list>
        property>
    
        
        <property name="list">
          <list>
            <value>小奥value>
            <value>小金value>
            <value>小普value>
          list>			
        property>
    
        
        <property name="map">
          <map>
            <entry key="aa" value="lucy">entry>
            <entry key="bb" value="mary">entry>
            <entry key="cc" value="tom">entry>
          map>
        property>
    
        
        <property name="properties">
          <props>
            <prop key="driverclass">com.mysql.jdbc.Driverprop>
            <prop key="username">rootprop>
          props>
        property>
    bean>
    
  1. 对象类型(重点)
  • 创建service类和dao类,在service得到dao对象(不通过new出来)

  • 具体实现过程

    • 在service里面把dao作为类型属性
    • 生成dao类型属性的set方法
    //1 定义dao类型属性
    private UserDao userDao;
    //2 生成set方法
    public void setUserDao(UserDao userDao) {
      this.userDao = userDao;
    }
    
    • xml配置文件中注入关系
    
    
    
    
    <bean id="userService" class="cn.itcast.ioc.UserService"> -->
      
      <property name="userDao" ref="userDao">property>
    bean>
    

3.属性注入(注解)


1 ) 导入jar包

基本jar包:
spring-beans.jar
spring-context.jar
spring-core.jar
spring-expression.jar
commons-logging.jar
log4j.jar

注解jar包:
spring-aop-4.2.4.jar

2 ) 创建spring配置文件,引入约束

  • spring配置文件中引入beans约束,context(schemaLocation属性中)注解约束

<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
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
beans>
  • 开启注解扫描

<context:component-scan base-package="cn.itcast">context:component-scan>



3 ) 具体注解

  • 注解创建对象

    @Component
    @Controller	:web层
    @Service	:业务层
    @Repository	:持久层
    
    @Scope(value="")
    	不写这个属性默认是单实例
    	具体见上面的:Bean标签常用属性知识点
    
  • 注解注入属性

    • 目标:创建service类,创建dao类,在service得到对象
    • 创建dao和service对象(并注解创建对象)
    • 在service类里面定义dao类型属性(两个注解都可以实现)
    • 使用注解方式时候不需要set方法
    第一个注解方式:
    //得到dao对象
    //1 定义dao类型属性
    //在dao属性上面使用注解 完成对象注入
    @Autowired
    private UserDao userDao;
    
    第二个注解方式:(更直观)
    // name属性值 写 注解创建dao对象 value值
    @Resource(name="userDao")
    private UserDao userDao;
    
  • 默认使用规则

    创建对象操作使用配置文件,属性注入使用注解

4.spring的aop操作(aspectj)


1 ) 需要jar包/aop约束

aopalliance.jar
aspectjweaver.jar
spring-aop.jar
spring-aspects.jar

xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"                           

2 ) 使用表达式配置切入点

切入点: 实际增强的方法

常用表达式: 格式:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

例子:
(1)execution(* cn.itcast.aop.Book.add(..))---->*表示任意修饰;cn.itcast.aop.book类中的add(..)方法增强;add(..)中两个..表示任意参数
(2)execution(* cn.itcast.aop.Book.*(..))---->book类中的所有方法
(3)execution(* *.*(..))---->所有类中的所有方法
(4) 匹配所有save开头的方法 execution(* save*(..))
  • xml配置

    目标: 执行cn.itcast.aop.Book中的add()时,默认先执行MyBook中的增强方法
    
    xml配置(beans标签内):      
    
    <bean id="book" class="cn.itcast.aop.Book">bean>
    <bean id="myBook" class="cn.itcast.aop.MyBook">bean>
    
    
    <aop:config>
      
      <aop:pointcut expression="execution(* cn.itcast.aop.Book.*(..))" id="pointcut1"/>
      
      <aop:aspect ref="myBook">
        
        <aop:before method="before1" pointcut-ref="pointcut1"/>
        <aop:after-returning method="after1" pointcut-ref="pointcut1"/>
        <aop:around method="around1" pointcut-ref="pointcut1"/>
      aop:aspect>
    aop:config>
    
    环绕增强的实体类方法:
    //环绕通知
    //参数ProceedingJoinPoint会默认调用被增强的方法执行
    public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
      //方法之前
      System.out.println("方法之前.....");
      //执行被增强的方法
      proceedingJoinPoint.proceed();
      //方法之后
      System.out.println("方法之后.....");
    }
    
  • 注解

    • 创建对象

      <bean id="book" class="cn.itcast.aop.Book">bean>
      <bean id="myBook" class="cn.itcast.aop.MyBook">bean>
      
    • 在spring核心配置文件中,开启aop操作

      
      <aop:aspectj-autoproxy>aop:aspectj-autoproxy>
      
    • 在增强类上面使用注解完成aop操作

      @Aspect
      public class MyBook {
        //在方法上面使用注解完成增强配置
        @Before(value="execution(* cn.itcast.aop.Book.*(..))")
        public void before() {
          System.out.println("before.......");
        }
      }
      

      @Before :前置通知
      @AfterReturing :后置通知
      @Around :环绕通知
      @After :最终通知
      @AfterThrowing :异常抛出通知
      ​```

5.配置监听器


针对spring中服务器启动时加载配置文件,自动创建对象放到ServletContext域中,需要导入spring-web.jar

//在web.xml中配置

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>


<context-param>
  <param-name>contextConfigLocationparam-name>
  <param-value>classpath:bean1.xmlparam-value>
context-param>

注意:默认到WEB-INF下面找applicationContext.xml文件,实际我们不是放到这个路径也不叫这个名称,所以需要自己配置路径

6.如何使用jdbcTemplate


以及jdbcTemplate/jdbc/dbutils的对比,看spring笔记

7.事务


  • xml

    • 配置事务管理器

      
      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
        <property name="dataSource" ref="dataSource">property>
      bean>
      
    • 配置事务增强

      
      <tx:advice id="txadvice" transaction-manager="transactionManager">
        
        <tx:attributes>
          
          <tx:method name="account*" propagation="REQUIRED"/>
        tx:attributes>
      tx:advice>
      
    • 配置切面

      
      <aop:config>
        
        <aop:pointcut expression="execution(* cn.itcast.service.OrdersService.*(..))" id="pointcut1"/>
        
        
        <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
      aop:config>
      
  • 注解

    • 配置事务管理器

      
      <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource">property>
      bean>
      
    • 配置事务注解扫描

      
      <tx:annotation-driven transaction-manager="transactionManager"/>
      
    • 使用注解

      //有注解的类,类里面的所有方法都加事务管理
      @Transactional
      public class OrdersService() { 
      
      }
      

8.spring中所有注解


//创建对象(标注在类上)
@Component
@Controller	:web层
@Service	:业务层
@Repository	:持久层
//创建对象时是否使用单实例(标注在类上)
//不写这个属性默认是单实例
@Scope(value="") 

//引入别的类对象(标注在成员变量上)
@Autowired
@Resource(name="userDao")
      
//切面,指明这个类中用于方法增强(标注在类上)
@Aspect
//具体需要增强的方法(标注在方法上)
@Before			:前置通知
@AfterReturing	:后置通知
@Around			:环绕通知
@After			:最终通知
@AfterThrowing	:异常抛出通知

//操作数据时的事务管理(标注在类上,此时类中所有方法都会进行事务管理)
@Transactional

//扫面创建对象的注解
<context:component-scan base-package="cn.itcast">context:component-scan>


//扫描aop增强注解
<aop:aspectj-autoproxy>aop:aspectj-autoproxy>


<tx:annotation-driven transaction-manager="transactionManager"/>

二、springmvc

表现层框架

一站式框架

官方推荐配置文件: springmvc.xml

1.架构


spring+springmvc-总结_第1张图片

一个中心三大组件(springmvc核心)

一个中心: DispatcherServlet(前段控制器)

三大组件: HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、ViewResolver(视图解析器)

组件说明:

  • 前端控制器:相当于mvc中的c,整个流程的控制中心,由它调用其他组件处理用户请求,降低组件之间耦合性
  • 处理器映射器:负责根据用户请求url找到Handler即处理器,(通过包名+方法名+请求的@RequestMapping路径),springmvc提供了不同的映射器实现方式: 配置文件,实现接口,注解方式等等
  • 处理器适配器:根据处理器映射器甩过来的路径,找到对应的Handler之后执行Handler,Handler执行完后返回的ModelAndView给处理器适配器(相当于返回了处理之后的结果)
  • 处理器:也叫后端控制器,处理用户的具体请求并返回结果,这个需要程序员自己开发
  • 视图解析器:负责将处理结果生成view视图(就是对jsp页面进行解析渲染之后形成html返回给用户(解析: 有后端返回的数据需要前段解析并显示))
  • 视图:一般情况下需要通过页面标签或者页面模板技术将模型数据通过页面展示给用户,需要由程序员自己开发

2.组件配置


  • 配置前端控制器

    web.xml中:

    
    <servlet>
      <servlet-name>springmvc-firstservlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
      
      
      <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:springmvc.xmlparam-value>
      init-param>
    servlet>
    
    <servlet-mapping>
      <servlet-name>springmvc-firstservlet-name>
      
      <url-pattern>*.actionurl-pattern>
    servlet-mapping>
    
  • 组件注解自动扫描

    springmvc.xml中:

    
    <context:component-scan base-package="cn.itcast.springmvc.controller" />
    
  • 处理器映射器

    对类中标记了@RequestMapping的方法进行映射.

    根据@ResquestMapping定义的value中的url匹配@ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器。

    springmvc.xml中:

    
    <bean
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
    

    注解描述: @RequestMapping:定义请求url到处理器功能方法的映射

  • 处理器适配器

    对标记@RequestMapping的方法进行适配

    springmvc.xml中:

    
    <bean	class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
    
  • 注解驱动(相当于配置了处理器映射器处理器适配器)

    
    <mvc:annotation-driven />
    
  • 视图解析器

    springmv.xml中:

    
    
    <bean
         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      
      <property name="prefix" value="/WEB-INF/jsp/" />
      
      <property name="suffix" value=".jsp" />
    bean>
    

    逻辑视图名需要在controller中返回ModelAndView指定,比如逻辑视图名为ItemList,则最终返回的jsp视图地址:“WEB-INF/jsp/itemList.jsp”

    最终jsp物理地址:前缀+逻辑视图名+后缀

  • 例子:

    // @RequestMapping:里面放的是请求的url,和用户请求的url进行匹配
    // action可以写也可以不写
    @RequestMapping("/itemList.action")
    public ModelAndView queryItemList() {
    	// 创建页面需要显示的商品数据
    	List<Item> list = new ArrayList<>();
    	list.add(new Item(1, "1华为 荣耀8", 2399, new Date(), "质量好!1"));
    	list.add(new Item(2, "2华为 荣耀8", 2399, new Date(), "质量好!2"));
    	list.add(new Item(3, "3华为 荣耀8", 2399, new Date(), "质量好!3"));
    
    	// 创建ModelAndView,用来存放数据和视图
    	ModelAndView modelAndView = new ModelAndView();
    	// 设置数据到模型中
    	modelAndView.addObject("itemList", list);
    	// 设置视图jsp,需要设置视图的物理地址
    	// modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
    	// 配置好视图解析器前缀和后缀,这里只需要设置逻辑视图就可以了
    	// 视图解析器根据前缀+逻辑视图名+后缀拼接出来物理路径
    	modelAndView.setViewName("itemList");
    
    	return modelAndView;
    }
    

3.springmvc整合mybaits


整合目标:控制层采用springmvc、持久层使用mybatis实现。

  • 需要jar包(去李旭springmvc资料里面找)

    1.spring(包括springmvc)
    2.mybatis
    3.mybatis-spring整合包
    4.数据库驱动
    5.第三方连接池
    
  • 整合思路

    Dao层
    ​ 1、SqlMapConfig.xml,空文件即可,但是需要文件头。
    ​ 2、applicationContext-dao.xml
    ​ a)数据库连接池
    ​ b)SqlSessionFactory对象,需要spring和mybatis整合包下的
    ​ c)配置mapper文件扫描器

    Service层
    ​ 1、applicationContext-service.xml包扫描器,扫描@service注解的类
    ​ 2、applicationContext-trans.xml配置事务

    Controller层
    ​ 1、Springmvc.xml
    ​ a)包扫描器,扫描@Controller注解的类
    ​ b)配置注解驱动
    ​ c)配置视图解析器

    Web.xml文件
    ​ 1、配置spring
    ​ 2、配置前端控制器

    #这些文件看同级文件夹resource
    sqlMapConfig.xml
    applicationContext-dao.xml
    db.properties
    applicationContext-service.xml
    applicationContext-trans.xml
    springmvc.xml
    web.xml
    

4.参数绑定


1 ) 默认支持的参数类型

​ 使用在controller的方法形参内

  • HttpServletRequest、HttpServletResponse、HttpSession

    可以向原生态servlet一样获取域对象

  • ModelAndView、Model、ModelMap

    三者只能选择一个使用

    ModelAndView返回一个对象(对象中包括数据和页面地址)

    Model返回一个字符串(字符串是页面地址,数据直接放在了域对象中)

    ​ 是一个接口,Model向页面传递数据,View可以使用String返回值代替

    ModelMap是Model接口的实现类,使用Model和ModelMap效果一样,如果直接使用Mode,springmvc会自动实例化ModelMap.

    /**
     * 根据id查询商品
     */
    @RequestMapping("/itemEdit")
    public ModelAndView queryItemById(HttpServletRequest request) {
    	// 从request中获取请求参数
    	String strId = request.getParameter("id");
    	Integer id = Integer.valueOf(strId);
      	// 根据id查询商品数据
    	Item item = this.itemService.queryItemById(id);
    	// 把结果传递给页面
    	ModelAndView modelAndView = new ModelAndView();
    	// 把商品数据放在模型中
    	modelAndView.addObject("item", item);
    	// 设置逻辑视图
    	modelAndView.setViewName("itemEdit");
    	
    	return modelAndView;
    }
    
    @RequestMapping("/itemEdit")
    public String queryItemById(HttpServletRequest request, Model model) {
    	// 从request中获取请求参数
    	String strId = request.getParameter("id");
    	Integer id = Integer.valueOf(strId);
    	// 根据id查询商品数据
    	Item item = this.itemService.queryItemById(id);
    	// 把商品数据放在模型中
    	model.addAttribute("item", item);
    	//返回视图地址
    	return "itemEdit";
    }
    @RequestMapping("/itemEdit")
    public String queryItemById(HttpServletRequest request, ModelMap model) {
    	// 从request中获取请求参数
    	String strId = request.getParameter("id");
    	Integer id = Integer.valueOf(strId);
    	// 根据id查询商品数据
    	Item item = this.itemService.queryItemById(id);
    	// 把商品数据放在模型中
    	model.addAttribute("item", item);
    	
    	return "itemEdit";
    }
    

2 ) 绑定简单类型

​ 当请求的参数名称和处理器形参**名称一致**时会将请求参数与形参进行绑定,这样从Request取参数的方法就可以进一步简化

  • 整形:Integer、int

  • 字符串:String

  • 单精度:Float、float

  • 双精度:Double、double

  • 布尔型:Boolean、boolean

    • 对于布尔类型的参数,请求的参数值为true或false或者1或0
      请求url:http://localhost:8080/xxx.action?id=2&status=false

      处理器方法:
      public String editItem(Model model,Integer id,Boolean status)

  • @RequestParam

    使用@RequestParam常用于处理简单类型的绑定

    // value:参数名字,即入参的请求参数名字,如value=“itemId”表示请求的参数区中的名字为itemId的参数的值将传入
    
    // required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错TTP Status 400 - Required Integer parameter 'XXXX' is not present
    
    // defaultValue:默认值,表示如果请求中没有同名参数时的默认值
    
    @RequestMapping("/itemEdit")
    public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id,
    		ModelMap modelMap) {
    	// 根据id查询商品数据
    	Item item = this.itemService.queryItemById(id);
    	// 把商品数据放在模型中
    	modelMap.addAttribute("item", item);
    	return "itemEdit";
    }
    

    @RequestParam(…) Integer id 与直接使用 Integer id的区别 :

    ​ 例如: http://localhost:8080/project/item?item=1

    ​ 生效: @RequestParam(value = “item”, required = true, defaultValue = “1”) Integer id

    ​ 无效: Integer id

    ​ http://localhost:8080/project/item?id=1

    ​ 无效: @RequestParam(value = “item”, required = true, defaultValue = “1”) Integer id

    ​ 生效: Integer id

    ​ 本质上不加@RequestParam也可以获得参数,但是异常处理或者方便前端传参变化,建议使用注解

3 ) 绑定pojo类型

  • 使用pojo接收表单数据,要求:pojo对象中的属性名和表单中input的name属性一致

  • 提交的表单中不要有日期类型的数据,否则会报400错误,日期类型的数据需要用自定义参数绑定

  • 代码写法就是跟简单类型一样,现在是用类类型定义形参

    /**
     * 更新商品,绑定pojo类型
     */
    @RequestMapping("/updateItem")
    public String updateItem(Item item) {
    	// 调用服务更新商品
    	this.itemService.updateItemById(item);
    	// 返回逻辑视图
    	return "success";
    }
    

4 ) 绑定包装pojo

  • 包装类

    public class QueryVo {
    	private Item item;
    	//set/get。。。
    }
    
  • contrller层

    // 绑定包装数据类型
    @RequestMapping("/queryItem")
    public String queryItem(QueryVo queryVo) {
      System.out.println(queryVo.getItem().getId());
      System.out.println(queryVo.getItem().getName());
    
      return "success";
    }
    

5 ) 自定义参数绑定

例子: 根据业务需求自定义日期格式存储

  • 自定义converter转化器进行参数绑定

  • 自定义的转换器类

    //Converter
    //S:source,需要转换的源的类型
    //T:target,需要转换的目标类型
    public class DateConverter implements Converter<String, Date> {
    
    	@Override
    	public Date convert(String source) {
    		try {
    			// 把字符串转换为日期类型
    			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
    			Date date = simpleDateFormat.parse(source);
    			return date;
    		} catch (ParseException e) {
    			e.printStackTrace();
    		}
    		// 如果转换异常则返回空
    		return null;
    	}
    }
    
  • 配置Converer

    
    
    <mvc:annotation-driven conversion-service="conversionService" />
    
    
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
      	
    	<property name="converters">
    		<set>
    			<bean class="cn.itcast.springmvc.converter.DateConverter" />
    		set>
    	property>
    bean>
    

6 ) 高级参数绑定(这块儿其实有点懵逼,后期回归)

  • 表单数据->数组

    • 创建一个pojo类或者pojo包装类(类中有实体类对象Item和string[])
    • 在contrller中通过包装类直接获取到所有页面传过来的数封装到String[]中
    • 遍历String[]进行相关操作
    /**
     * 包装类型 绑定数组类型,可以使用两种方式,pojo的属性接收,和直接接收(直接接收就相当于简单类型绑定)
     *
     */
    @RequestMapping("queryItem")
    public String queryItem(QueryVo queryVo, Integer[] ids) {
    	System.out.println(queryVo.getItem().getId());
    	System.out.println(queryVo.getItem().getName());
    	System.out.println(queryVo.getIds().length);
    	System.out.println(ids.length);
      
    	return "success";
    }
    
  • 表单数据->List

    • controller中使用pojo类型接收
    • pojo类中定义一个成员变量: List itemList;

5.解决post/get请求数据保存到数据库乱码问题


  • post乱码

    web.xml中:

    	
    	<filter>
    		<filter-name>encodingfilter-name>
    		<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    		
    		<init-param>
    			<param-name>encodingparam-name>
    			<param-value>UTF-8param-value>
    		init-param>
    	filter>
    	<filter-mapping>
    		<filter-name>encodingfilter-name>
    		<url-pattern>/*url-pattern>
    	filter-mapping>
    
  • get乱码

    方式一:

    修改tomcat配置文件添加编码与工程编码一致,如下:(server.xml)

    <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    

    方式二:

    对参数进行重新编码:

    String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
    //ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
    

6.@RequestMapping


​ @RequestMapping(value=“item”)或@RequestMapping(“/item”)

  • value的值是数组,可以将多个url映射到同一个方法中

    • @RequestMapping(value = { “itemList”, “itemListAll” })
  • 使用方式

    • 类上: 在class上@RequestMapping(url)指定通用请求前缀,限制此类下的所有方法请求url必须以请求前缀开头!

    • 方法上

      可以限定post/get方法才可以请求该方法(默认不指定是都可以请求)

      @RequestMapping(method = RequestMethod.GET)

      @RequestMapping(value = “itemList”,method = RequestMethod.POST)

      //post/get都可以访问

      @RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})

7.@RequestBody and @ResponseBody


​ 注意使用需要导入json的jar包: jackson

  • @RequestBody

    post请求体中json数据给Controller,@RequestBody负责把json数据转为java对象并绑定到Controller方法的形参上

    {
    	"id": 1,
    	"name": "测试商品",
    	"price": 99.9,
    	"detail": "测试商品描述",
    	"pic": "123456.jpg"
    }
    #@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象进行绑定
    #通过springmvc提供的HttpMessageConverter接口
    
  • @ResponseBody

    @ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

    /**
     * 测试json的交互
     * 请求是json,返回也是json,证明json解析到Item对象,Item封装到json,都是正确的
     */
    @RequestMapping("testJson")
    public @ResponseBody Item testJson(@RequestBody Item item) {
    	return item;
    }
    
  • 如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,只会返回的json数据。如果不加,就走视图解析器,返回页面

8.Controller方法返回值


  • ModelAndView

  • void(不使用,springmvc有自己的重定向方法,返回值是String)

    • 使用Servlet中的request/response转发、重定向、指定响应结果
    /**
     * 返回void测试
     */
    @RequestMapping("queryItem")
    public void queryItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	// 1 使用request进行转发
    	//request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,
    	// response);
    
    	// 2 使用response进行重定向到编辑页面
    	// response.sendRedirect("/springmvc-web2/itemEdit.action");
    
    	// 3 使用response直接显示
    	response.getWriter().print("{\"abc\":123}");
    }
    
    //知识补充:
    //转发之后request和response域中对象不会失效,但是重定向就会失效
    //转发就相当于连个jsp页面拼起来,重定向则是换了一个新的jsp(这也是域对象会失效的原因)
    //转发浏览器地址不会改变,重定向会改变(转发是偷梁换柱暗度陈仓,重定向是光明磊落说一不二)
    
  • string

    • 逻辑视图名

      • Model
      • ModelMap
    • Redirect重定向

      @RequestMapping("updateItem")
      public String updateItemById(Item item) {
      	// 更新商品
      	this.itemService.updateItemById(item);
      
      	// 修改商品成功后,重定向到商品编辑页面
      	// 重定向后浏览器地址栏变更为重定向的地址,
      	// 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
      	// 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
      	return "redirect:/itemEdit.action?itemId=" + item.getId();
      }
      
    • forward转发

      @RequestMapping("updateItem")
      public String updateItemById(Item item) {
      	// 更新商品
      	this.itemService.updateItemById(item);
      
      	// 修改商品成功后,继续执行另一个方法
      	// 使用转发的方式实现。转发后浏览器地址栏还是原来的请求地址,
      	// 转发并没有执行新的request和response,所以之前的请求参数都存在
      	return "forward:/itemEdit.action";
      }
      

9.RESTful风格


​ Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

​ 传统方式操作资源-> http://127.0.0.1/item/queryItem.action?id=1 查询,GET

​ 使用RESTful操作资源-> http://127.0.0.1/item/1 查询,GET

  • 需求: RESTful方式实现商品信息查询,返回json数据

  • 实现

    • 从url上获取参数

    • 我们需要从url上获取商品id,步骤如下:

      1. 使用注解**@RequestMapping(“item/{id}”)**声明请求的url

        {xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”

      2. 使用(@PathVariable() Integer id)获取url上的数据

      /**
       * 使用RESTful风格开发接口,实现根据id查询商品
       * 请求路径: http://127.0.0.1/item/1
       * Variable-变量
       */
      @RequestMapping("item/{id}")
      @ResponseBody
      public Item queryItemById(@PathVariable() Integer id) {
      	Item item = this.itemService.queryItemById(id);
      	return item;
      }
      
      // 如果@RequestMapping中表示为"item/{id}",id和形参名称一致
      	// @PathVariable不用指定名称;
      // 如果不一致,例如"item/{ItemId}"
        	// 则需要指定名称@PathVariable("itemId")
      
    • @PathVariable是获取url上数据的。@RequestParam获取请求参数的(包括post表单提交)

10.上传图片


  1. 配置虚拟目录

    server.xml中:

    
    #相当于是虚拟路经和真是路径绑定
    <Context docBase="D:\develop\upload\temp" path="/pic" reloadable="false"/>
    
  2. 导入jar

    commons-fileupdate-1.2.2.jar

    commons-io-2.4.jar

  3. 配置传解析器

    springmvc.xml中:

    
    <bean id="multipartResolver"
    	class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	
    	<property name="maxUploadSize" value="5000000" />
    bean>
    
  4. 代码

    /**
     * 更新商品
     */
    @RequestMapping("updateItem")
    public String updateItemById(Item item, MultipartFile pictureFile) throws Exception {
    	// 图片上传
    	// 设置图片名称,不能重复,可以使用uuid
    	String picName = UUID.randomUUID().toString();
    	// 获取文件名
    	String oriName = pictureFile.getOriginalFilename();
    	// 获取图片后缀
    	String extName = oriName.substring(oriName.lastIndexOf("."));
    	// 开始上传
    	pictureFile.transferTo(new File("C:/upload/image/" + picName + extName));
    	// 设置图片名到商品中
    	item.setPic(picName + extName);
    	// ---------------------------------------------
    	// 更新商品
    	this.itemService.updateItemById(item);
    
    	return "forward:/itemEdit.action";
    }
    

11.异常处理器


​ 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
spring+springmvc-总结_第2张图片

  • 自定义异常类

    public class MyException extends Exception {
    	// 异常信息
    	private String message;
      	//有参和无参构造
    	public MyException() {
    		super();
    	}
    	public MyException(String message) {
    		super();
    		this.message = message;
    	}
      	//set\get(message)
    	public String getMessage() {
    		return message;
    	}
    	public void setMessage(String message) {
    		this.message = message;
    	}
    }
    
  • 自定义异常处理类

    public class CustomHandleException implements HandlerExceptionResolver {
    	@Override
    	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
    			Exception exception) {
    		// 定义异常信息
    		String msg;
    		// 判断异常类型
          	//instanceof 是否属于某个类(是否是谁的实例)
    		if (exception instanceof MyException) {
    			// 如果是自定义异常,读取异常信息
    			msg = exception.getMessage();
    		} else {
    			// 如果是运行时异常,则取错误堆栈,从堆栈中获取异常信息
    			Writer out = new StringWriter();
    			PrintWriter s = new PrintWriter(out);
    			exception.printStackTrace(s);
    			msg = out.toString();
    		}
    		// 把错误信息发给相关人员,邮件,短信等方式
    		// TODO
    		// 返回错误页面,给用户友好页面显示错误信息
    		ModelAndView modelAndView = new ModelAndView();
    		modelAndView.addObject("msg", msg);
    		modelAndView.setViewName("error");
    		return modelAndView;
    	}
    }
    
  • springmvc.xml配置

    
    <bean 
    id="customHandleException" 	class="cn.itcast.ssm.exception.CustomHandleException"/>
    
  • 测试异常类

    /**
     * 查询商品列表
     */
    @RequestMapping(value = { "itemList", "itemListAll" })
    public ModelAndView queryItemList() throws Exception {
    	// 自定义异常
    	if (true) {
    		throw new MyException("自定义异常出现了~");
    	}
    	// 运行时异常
    	int a = 1 / 0;
    	// 查询商品数据
    	List<Item> list = this.itemService.queryItemList();
    	// 创建ModelAndView,设置逻辑视图名
    	ModelAndView mv = new ModelAndView("itemList");
    	// 把商品数据放到模型中
    	mv.addObject("itemList", list);
    	return mv;
    }
    

12.拦截器


​ 类似于servlet中的Filter过滤器,用于对处理器进行预处理和后处理

  • 自定义拦截器

    // 实现HandlerInterceptor接口
    public class HandlerInterceptor1 implements HandlerInterceptor {
    	// controller执行后且视图返回后调用此方法
    	// 这里可得到执行controller时的异常信息
    	// 这里可记录操作日志
    	@Override
    	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    			throws Exception {
    		System.out.println("HandlerInterceptor1....afterCompletion");
    	}
    	// controller执行后但未返回视图前调用此方法
    	// 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
    	@Override
    	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    			throws Exception {
    		System.out.println("HandlerInterceptor1....postHandle");
    	}
    	// Controller执行前调用此方法
    	// 返回true表示继续执行,返回false中止执行
    	// 这里可以加入登录校验、权限拦截等
    	@Override
    	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    		System.out.println("HandlerInterceptor1....preHandle");
    		// 设置为true,测试使用
    		return true;
    	}
    }
    
  • 拦截器配置

    springmvc.xml中:

    
    <mvc:interceptors>
    	<mvc:interceptor>
    		
    		<mvc:mapping path="/**" />
    		
    		<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />
    	mvc:interceptor>
    	<mvc:interceptor>
    		
    		<mvc:mapping path="/**" />
    		
    		<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />
    	mvc:interceptor>
    mvc:interceptors>
    
  • 多个拦截器执行顺序(一般之定义一个拦截器)

    总结:

    preHandle按拦截器定义顺序调用

    postHandler按拦截器定义逆序调用

    afterCompletion按拦截器定义逆序调用

    postHandler在拦截器链内所有拦截器返成功调用

    afterCompletion只有preHandle返回true才调用

  • 拦截器应用实例(判断用户是否登录)

    • 见外层文件夹resource中的 登录状态判断

13.springmvc中所有注解


//匹配访问路径(类上、方法上)
@RequestMapping
//获取请求参数(controller方法形参内)
@RequestParam
//前端给的json串解析成java对象,映射在形参对象里(controller方法形参内)
@RequestBody
//返给前端的对象解析成一个json串(controller方法中,返回值位置)
@ResponseBody
//获取url上数据(controller方法形参内)
@PathVariable
#前端控制器
web.xml

#处理器映射器
springmvc.xml
#处理器适配器
springmvc.xml
#注解驱动(相当于配置了==处理器映射器==和==处理器适配器==)



#视图解析器
springmvc.xml

#解决post/get请求数据保存到数据库乱码问题
web.xml

#上传图片(配置虚拟目录)
server.xml

#配置全局异常处理器
springmvc.xml

#拦截器配置
springmvc.xml

#具体配置详情见每一项小标题具体说明

你可能感兴趣的:(JavaWeb,spring,springmvc)