springmvc

来源:互联网 发布:淘宝助理报告错误 编辑:程序博客网 时间:2024/06/06 02:24

SpringMVC入门

web.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns: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">

 

    <!-- 配置前端控制器 -->

    <servlet>

       <servlet-name>springmvc</servlet-name>

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

       <!-- 指定DispatcherServlet的配置文件 -->

       <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:springmvc.xml</param-value>

       </init-param>

    </servlet>

    <servlet-mapping>

       <servlet-name>springmvc</servlet-name>

       <!-- 拦截配置方式有两种正确和一种错误的 -->

       <!-- 第一种:*.do拦截以.do结尾的-->

       <!-- 第二种:/,会拦截所有请求(不包括jsp请求),会包括静态资源(CSSjs、图片、html页面,只需要设置静态资源拦截规则就可以访问),还可以满足restful请求的url -->

       <!-- 第三种:/*,这种配置是错误的,会拦截所有请求(包括jsp请求)-->

       <url-pattern>*.do</url-pattern>

    </servlet-mapping>

</web-app>

config/springmvc.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 使用注解扫描器,配置处理器,扫描包内 -->

    <context:component-scanbase-package="com.itjava.springmvc.first" />

</beans>

package com.itjava.springmvc.first;

import java.util.ArrayList;

import java.util.List;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

import com.itjava.springmvc.po.Items;

@Controller

public class ItemsController {

    @RequestMapping("/queryItems")

    public ModelAndView queryItems() {

       // 调用service方法,返回商品列表(使用静态数据模拟)

       List<Items> itemList = new ArrayList<>();

       // 商品列表

       Items items_1 = new Items();

       items_1.setName("联想笔记本_3");

       items_1.setPrice(6000f);

       items_1.setDetail("ThinkPad T430联想笔记本电脑!");

       Items items_2 = new Items();

       items_2.setName("苹果手机");

       items_2.setPrice(5000f);

       items_2.setDetail("iphone6苹果手机!");

       itemList.add(items_1);

       itemList.add(items_2);

       ModelAndView mv = new ModelAndView();

       // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

       mv.addObject("itemsList",itemList);

       // 指定视图名称

       mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp");

       returnmv;

    }

}

访问路径:端口号/项目名/queryItems.do

如何开发处理器(Controller类)

       1. 类上加Controller注解

2. 方法上加RequestMapping注解

3. 还有其他开发方式(实现HttpRequestHandler接口、实现Controller接口,此两种仅作了解)

实现HttpRequestHandler接口

package com.itjava.springmvc.first;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.HttpRequestHandler;

import com.itjava.springmvc.po.Items;

public class ItemsController2 implements HttpRequestHandler {

    @Override

    public void handleRequest(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       // 调用service方法,返回商品列表(使用静态数据模拟)

       List<Items> itemList = new ArrayList<>();

       // 商品列表

       Items items_1 = new Items();

       items_1.setName("联想笔记本_3");

       items_1.setPrice(6000f);

       items_1.setDetail("ThinkPad T430联想笔记本电脑!");

       Items items_2 = new Items();

       items_2.setName("苹果手机");

       items_2.setPrice(5000f);

       items_2.setDetail("iphone6苹果手机!");

       itemList.add(items_1);

       itemList.add(items_2);

       // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

       request.setAttribute("itemsList",itemList);

       // 指定视图名称,不会经过视图解析器

       request.getRequestDispatcher("/WEB-INF/jsp/item/itemsList.jsp").forward(request,response);

    }

}

访问路径:端口号/项目名/queryItems2.do

实现Controller接口

package com.itjava.springmvc.first;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;

import com.itjava.springmvc.po.Items;

public class ItemsController3 implements Controller {

    @Override

    public ModelAndView handleRequest(HttpServletRequestrequest, HttpServletResponse response) throws Exception {

       // 调用service方法,返回商品列表(使用静态数据模拟)

       List<Items> itemList = new ArrayList<>();

       // 商品列表

       Items items_1 = new Items();

       items_1.setName("联想笔记本_3");

       items_1.setPrice(6000f);

       items_1.setDetail("ThinkPad T430联想笔记本电脑!");

       Items items_2 = new Items();

       items_2.setName("苹果手机");

       items_2.setPrice(5000f);

       items_2.setDetail("iphone6苹果手机!");

       itemList.add(items_1);

       itemList.add(items_2);

       ModelAndView mv = new ModelAndView();

       // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

       mv.addObject("itemsList",itemList);

       // 指定视图名称

       mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp");

       returnmv;

    }

}

访问路径:端口号/项目名/queryItems3.do

config/springmvc.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 使用注解扫描器,配置处理器,按包匹配扫描,多个包中间使用半角逗号分隔-->

    <context:component-scanbase-package="com.itjava.springmvc.first" />

    <!-- 配置实现HttpRequestHandler接口的处理器,下面两种不需要注解扫描器-->

    <beanname="/queryItems2.do"class="com.itjava.springmvc.first.ItemsController2"></bean>

    <beanname="/queryItems3.do"class="com.itjava.springmvc.first.ItemsController3"></bean>

</beans>

springmvc架构(重点)

架构流程

1. 用户发送请求至前端控制器DispatcherServlet

2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器

5. HandlerAdapter执行处理器(handler,也叫后端控制器)。

6. Controller执行完成返回ModelAndView

7. HandlerAdapter将handler执行结果ModelAndView返回给DispatcherServlet

8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器

9. ViewReslover解析后返回具体View对象

10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。

11. DispatcherServlet响应用户

springmvc的各个组件中,处理器映射器、处理器适配器、视图解析器称为springmvc的三大组件。

需要用户开发的组件有:处理器、视图

在config/springmvc..xml配置文件中

    <!-- 配置注解映射器和适配器,配置这两行代码后,非注解的访问会报错 -->

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

    <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!-- 使用mvc标签配置注解和非注解映射器和适配器,配置下面的代码可注释上面的两行代码 -->

    <!-- 该配置就默认配置注解方式的映射器和适配器,还配置了参数绑定组件,比如json参数绑定组件 -->

    <mvc:annotation-driven/>

    <!--  配置视图解析器 -->

    <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <!--  视图解析器配置前缀,返回视图会自动添加此前缀 -->

       <propertyname="prefix"value="/WEB-INF/jsp/"/>

       <!--  视图解析器配置后缀,返回视图会自动添加此后缀-->

       <propertyname="suffix"value=".jsp"/>

       <!--  mv.setViewName("/WEB-INF/jsp/item/itemsList.jsp");可改为mv.setViewName("item/itemsList");//此称之为逻辑视图-->

    </bean>

整合ssm

自定义转换器,转换日期格式

package com.itjava.ssm.controller.converter;

import java.text.SimpleDateFormat;

import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class DateConverter implements Converter<String, Date> {

    @Override

    public Date convert(Stringsource) {

       try {

           SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

           returnformat.parse(source);

       } catch (Exceptione) {

           e.printStackTrace();

       }

       return null;

    }

config/mybatis/SqlMapConfig.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPEconfiguration

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

</configuration>

config/spring/applicationContext-dao.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:tx="http://www.springframework.org/schema/tx"

    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-4.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-4.0.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

    http://www.springframework.org/schema/util

    http://www.springframework.org/schema/util/spring-util-4.0.xsd">

 

    <!-- 读取java配置文件 -->

    <context:property-placeholderlocation="classpath:db.properties"/>

 

    <!-- 配置数据源,使用dbcp连接池 -->

    <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"

       destroy-method="close">

       <propertyname="driverClassName"value="${jdbc.driver}"/>

       <propertyname="url"value="${jdbc.url}"/>

       <propertyname="username"value="${jdbc.username}"/>

       <propertyname="password"value="${jdbc.password}"/>

       <propertyname="maxActive"value="10"/>

       <propertyname="maxIdle"value="5"/>

    </bean>

 

    <!-- 配置SqlSessionFactory -->

    <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">

       <!-- 指定mybatis的全局配置文件路径 -->

       <propertyname="configLocation"value="classpath:mybatis/SqlMapConfig.xml"/>

       <!-- 指定数据源 -->

       <propertyname="dataSource"ref="dataSource"></property>

       <!-- 指定类型别名 -->

       <propertyname="typeAliasesPackage"value="com.itjava.ssm.po"></property>

    </bean>

 

    <!-- 批量代理mapper对象 -->

    <beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">

       <!-- 注入批量代理的mapper对象所在的包名 -->

       <propertyname="basePackage"value="com.itjava.ssm.mapper"></property>

    </bean>

</beans>

config/spring/applicationContext-service.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:tx="http://www.springframework.org/schema/tx"

    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-4.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-4.0.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd

    http://www.springframework.org/schema/tx

    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

    http://www.springframework.org/schema/util

    http://www.springframework.org/schema/util/spring-util-4.0.xsd">

 

    <!-- 通过组件扫描器,加载servicebean -->

    <context:component-scanbase-package="com.itjava.ssm.service"></context:component-scan>

 

    <!-- 配置事务管理器 -->

    <beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

       <propertyname="dataSource"ref="dataSource"></property>

    </bean>

 

    <!-- 配置通知 -->

    <tx:adviceid="txAdvice"transaction-manager="transactionManager">

       <tx:attributes>

           <!-- 配置事务传播特性,name指的就是业务方法的名称,可以使用通配符 -->

           <tx:methodname="save*"propagation="REQUIRED"/>

           <tx:methodname="add*"propagation="REQUIRED"/>

           <tx:methodname="insert*"propagation="REQUIRED"/>

           <tx:methodname="delete*"propagation="REQUIRED"/>

           <tx:methodname="del*"propagation="REQUIRED"/>

           <tx:methodname="remove*"propagation="REQUIRED"/>

           <tx:methodname="update*"propagation="REQUIRED"/>

           <tx:methodname="modify*"propagation="REQUIRED"/>

           <tx:methodname="find*"read-only="true"/>

           <tx:methodname="query*"read-only="true"/>

           <tx:methodname="select*"read-only="true"/>

           <tx:methodname="get*"read-only="true"/>

       </tx:attributes>

    </tx:advice>

 

    <!-- 配置AOP -->

    <aop:config>

       <aop:advisoradvice-ref="txAdvice"pointcut="execution(* com.itjava.ssm.service.impl.*.*(..))"/>

    </aop:config>

 

</beans>

config/spring/springmvc.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

    http://www.springframework.org/schema/context

    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 使用注解扫描器,配置处理器 -->

    <context:component-scanbase-package="com.itjava.ssm.controller"/>

    <!-- 使用mvc标签配置注解映射器和适配器 -->

    <!-- 该配置就默认配置注解方式的映射器和适配器,还配置了参数绑定组件,比如json参数绑定组件 -->

    <!--  如果不配置自定义转换器,则删除conversion-service="conversionService" -->

    <mvc:annotation-drivenconversion-service="conversionService"/>

 

<!--  配置视图解析器 -->

    <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <propertyname="prefix"value="/WEB-INF/jsp/"/>

        <propertyname="suffix"value=".jsp"/>

    </bean>

    <!-- 配置自定义转换器 -->

    <beanid="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

       <propertyname="converters">

           <set>

              <beanclass="com.itjava.ssm.controller.converter.DateConverter"></bean>

           </set>

       </property>

    </bean>

</beans>

web.xml

<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns: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">

    <!-- 配置前端控制器 -->

    <servlet>

       <servlet-name>springmvc</servlet-name>

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

       <!-- 指定DispatcherServlet的配置文件 -->

       <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:spring/springmvc.xml</param-value>

       </init-param>

    </servlet>

    <servlet-mapping>

       <servlet-name>springmvc</servlet-name>

       <url-pattern>*.do</url-pattern>

    </servlet-mapping>

   

    <context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>classpath:spring/applicationContext-*.xml</param-value>

    </context-param>

    <listener>

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

 

    <!-- 解决POST乱码 -->

    <filter>

       <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

</web-app>

对象传递

service层

@Service

public class ItemsServiceImpl implements ItemsService {

    @Autowired

    private ItemsMappermapper;

    // 代码...

}

controller层

@RequestMapping("/items")

@Controller

public class ItemsController {

    @Autowired

    private ItemsServiceservice;

    // 代码...

}

什么是参数绑定?

客户端通过http请求的参数,默认是key/value格式(http://XXXXX?id=1&type=301)的字符串,springmvc通过参数绑定组件将请求参数串的value进行类型转换,将转换后的值赋值给controller方法的形参,这就是参数绑定的过程

springmvc使用controller方法形参接收请求的参数

struts2通过成员变量接收请求的参数

参数绑定之简单类型

直接绑定

访问路径端口号/项目名/itemsEdit.do?id=1

http请求的key的名称和controller方法的形参名称一致,就能直接绑定成功

注解绑定

如果key与参数名不一致如(key=itemsid)则如下解决,但访问时必须带参数值,不然报错,默认必须带参数

@RequestMapping("/itemsEdit")

public ModelAndView itemsEdit(@RequestParam("itemsid") Integerid)

下面和上面一样,无参数值则默认为2, required =true可省略

@RequestMapping("/itemsEdit")

public ModelAndView itemsEdit(@RequestParam(value ="itemsid", required = true, defaultValue ="2") Integer id)

@Controller

public class ItemsController {

    @Autowired

    private ItemsServiceservice;

     @RequestMapping("/itemsEdit")

     public ModelAndView itemsEdit(Integerid) {

     Items items = service.queryItemsById(id);

     ModelAndView mv = new ModelAndView();

     // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

     mv.addObject("items",items);

     // 指定视图名称

     mv.setViewName("item/editItems");

     return mv;

     }

}

参数绑定之pojo类型

访问路径端口号/项目名/itemsEdit.do?id=1&name=张三&age=20访问方式为POST

@Controller

public class ItemsController {

    @Autowired

    private ItemsServiceservice;

     @RequestMapping("/itemsEdit")

     // id会分配给iduser中的id

     public ModelAndView itemsEdit(Integerid ,User user) {

     ModelAndView mv = new ModelAndView();

     // 代码...

     return mv;

     }

}

已在web.xml配置

绑定包装pojo类

key值为items.name,接收参数为QueryVO,QueryVO中有属性items,items中有name属性,即可接收到

自定义参数绑定

由于日期数据有很多种格式,所以springmvc没办法把字符串转换成统一的日期类型。所以需要自定义参数绑定。

前端控制器接收到请求后,找到处理器适配器,适配器在执行处理器时,对方法中的形参进行参数绑定。所以如果自定义参数绑定组件的话,需要将该参数组件绑定到处理器适配器上。如果使用<mvc:annotation-driven/>可以在此标签上进行扩展

已在前面的代码及配置文件配置

 

springmvc与struts2不同

1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

绑定数组

如果页面传递的请求参数中,是一个集合参数,并且是简单类型的,这个时候只能使用数组来接收,不能使用List

对于这种批量操作简单类型数据的情况,Controller方法中可以用String[]接收,或者pojo的String[]属性接收,但是不能使用集合接收。两种方式任选其一即可,比如根据id批量删除商品信息

将表单的数据绑定到List

如果页面传递的请求参数中,是一个集合参数,并且是POJO类型的,这个时候可以使用数组也可以使用List来接收,但是不能将数组或者List直接声明在Controller的方法中,只能通过一个POJO来包装它们然后接收

Item中有userList(user的List集合或数组集合)

方法的参数名为(Item item)

传递的参数name="userList[0].username"即可

URL路径映射:在方法上

@RequestMapping(value="/items")或@RequestMapping("/items")

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

@RequestMapping(value={"/items","/queryItems"})

窄化请求映射

在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。

如下:

@RequestMapping放在类名上边,设置请求前缀

@Controller

@RequestMapping("/items")

方法名上边设置请求映射url:

@RequestMapping放在方法名上边,如下:

@RequestMapping("/queryitems")

访问地址为:/items/queryItems.do

请求方法限定:在类上

限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'POST' not supported

例如:

@RequestMapping(value="/edititems",method=RequestMethod.GET)

限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通过Post访问则报错:

HTTP Status 405 - Request method 'GET' not supported

GET和POST都可以

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

controller方法返回值

返回ModelAndView

controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。

返回void

       在controller方法形参上可以定义request和response,使用request或response指定响应结果:

1、使用request转发页面,如下:

request.getRequestDispatcher("页面路径").forward(request, response);

2、也可以通过response页面重定向:

response.sendRedirect("url")

3、也可以通过response指定响应结果,例如响应json数据如下:

response.setCharacterEncoding("utf-8");

response.setContentType("application/json;charset=utf-8");

response.getWriter().write("json串");

返回字符串(推荐)

逻辑视图名

controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

方法参数中有org.springframework.ui.Model model

    public String queryItems(ItemsQueryVOvo, Model model, HttpServletRequestrequest) {

       System.out.println("ID:" +request.getParameter("id"));

       // 调用service方法,返回商品列表(使用静态数据模拟)

       List<Items> itemList = service.queryItemsList();

       // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

       model.addAttribute("itemsList",itemList);

       return"item/itemsList";

    }

//指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/items/edititems.jsp

return "items/editItems";

Redirect重定向

Contrller方法返回结果重定向到一个url地址,如下商品修改提交后重定向到商品查询方法,参数无法带到商品查询方法中。

//重定向到queryitems.action地址,request无法带过去

return "redirect:queryItems.do";

redirect方式相当于“response.sendRedirect()”,转发后浏览器的地址栏变为转发后的地址,因为转发即执行了一个新的request和response。

由于新发起一个request原来的参数在转发时就不能传递到下一个url,如果要传参数可以/items/queryitems.do后边加参数,如下:

/items/queryitems?...&…..

forward转发

controller方法执行后继续执行另一个controller方法,如下商品修改提交后转向到商品列表页面,修改商品的id参数可以带到商品列表方法中。

return "forward:queryItems.do";

forward方式相当于“request.getRequestDispatcher().forward(request,response)”,转发后浏览器地址栏还是原来的地址。转发并没有执行新的request和response,而是和转发前的请求共用一个request和response。所以转发前请求的参数在转发后仍然可以读取到。

异常处理器

package com.itjava.ssm.exception;

public class BusinessException extends Exception {

    private Stringmessage;

    public String getMessage() {

       returnmessage;

    }

    public void setMessage(String message) {

       this.message =message;

    }

    public BusinessException(Stringmessage) {

       super();

       this.message =message;

    }

}

import com.itjava.ssm.exception.BusinessException;

    public String itemsEdit(Integerid, Model model)throws Exception {

       Items items = service.queryItemsById(id);

       if (items ==null)

           throw new BusinessException("根据该商品ID无法查找商品数据!");

       // 本质上就和request.setAttribute的功能一样,就是将数据放入request域中

       model.addAttribute("items",items);

       return"item/editItems";

    }

package com.itjava.ssm.exception.resolver;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;

import org.springframework.web.servlet.ModelAndView;

import com.i tjava.ssm.exception.BusinessException;

public class BusinessExceptionResolver implements HandlerExceptionResolver {

    @Override

    public ModelAndView resolveException(HttpServletRequestrequest, HttpServletResponse response, Object handler, Exception ex) {

       //获取异常错误信息

       String msg = "未知错误";

       if (exinstanceof BusinessException) {

           BusinessException bx = (BusinessException)ex;

           msg = bx.getMessage();

       }

       ModelAndView mv = new ModelAndView();

       //将异常信息封装到request域中

       mv.addObject("msg",msg);

       //在错误页面显示

       mv.setViewName("error");

       returnmv;

    }

}

springmvc.xml中

    <!-- 配置异常处理器 -->

    <beanclass="com.itjava.ssm.exception.resolver.BusinessExceptionResolver"></bean>

上传图片

springmvc.xml中

    <!-- 多部件解析器 -->

<beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

       <!--  设置上传文件的最大尺寸 5M ,,单位是byte -->

       <propertyname="maxUploadSize"value="5242880"/>

    </bean>

    @RequestMapping("/updateItems")

    public String updateItems(Integerid, Items items, MultipartFilepictureFile) throws Exception{

       if (pictureFile !=null) {

           // 目的是为了获取上传文件的扩展名

           String originalFilename =pictureFile.getOriginalFilename();

           // 判断文件名称不为空

           if (originalFilename !=null && !"".equals(originalFilename)) {

              // 获取扩展名

              String extName =originalFilename.substring(originalFilename.lastIndexOf("."));

              // 创建新的文件名称

              String newFileName = UUID.randomUUID().toString() +extName;

              // 指定文件生成之后的目录

              String dir = "E:\\03-teach\\07-upload\\temp\\";

              // 判断如果目录不存在,则创建

              File dirFile = new File(dir);

              if (!dirFile.exists()) {

                  dirFile.mkdirs();

              }

              //上传文件到指定目录

              pictureFile.transferTo(new File(dir+newFileName));

              //保存上传文件名称

              items.setPic(newFileName);

           }

       }

       // 调用service的方法进行修改

       service.updateItems(items);

       // 重定向

       // return "redirect:queryItems.do";

       // 请求转发

       return"forward:queryItems.do";

    }

配置图片文件的虚拟目录

1. 通过eclipse配置tomcat的虚拟目录

2. 直接修改tomcat的配置文件

tomcat安装目录中的conf/server.xml文件中,添加虚拟目录:

<Context docBase="E:\03-teach\07-upload\temp" path="/pic" reloadable="false"/>

json数据交互

用户发出请求

请求参数是json串(必须外面单引里面双引)

data : '{"name":"zhangsan","price":999}'

需要指定

contentType=application/json;charset=utf-8

 

请求参数是key/value

data : "name=zhangsan&price=999"

不需要指定contentType

默认contentType=application/x-www-form-urlencoded

使用@RequestBody将json串转成java对象

不用@RequestBody

使用@ResponseBody将返回值的java对象转成json串输出

    @RequestMapping("/requestJSON")

    @ResponseBody

    public Items requestJSON(@RequestBody Itemsitems){

       returnitems;

    }

使用@ResponseBody将返回值的java对象转成json串输出

    @RequestMapping("/requestKV")

    @ResponseBody

    public Items requestKV(Itemsitems){

       returnitems;

    }

最终都是输出了json串到页面,方便客户端解析

RESTful支持

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。

普通URL:

http://localhost:8080/ssm/queryItemsById.do?id=1

restful风格URL

http://localhost:8080/ssm/items/1

uri:统一资源定位符ssm/queryItemsById

httpMethod有7种:其中获取资源使用get方式、添加资源使用post方式、删除资源使用delete方式、修改资源使用put方式。

Restful风格要求三个规范:

1、  要求URL要规范

2、  要求httpmethod方法要被利用(不用在意)

3、  要求返回格式是由调用人员指定

注意:restful风格的请求URL只会在GET方式的请求过程中和普通请求方式有所区别

在web.xml将拦截规则改为

    <servlet>

       <servlet-name>springmvc</servlet-name>

       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

       <!-- 指定DispatcherServlet的配置文件 -->

       <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>classpath:spring/springmvc.xml</param-value>

       </init-param>

    </servlet>

    <servlet-mapping>

       <servlet-name>springmvc</servlet-name>

       <url-pattern>/</url-pattern>

    </servlet-mapping>

根据需求,设计的restful风格的请求url如下:

http://localhost:8280/ssm2/queryItemsById/1

    // 参数名不相同的格式

    @RequestMapping("/queryItemsById/{itemsId}")

    @ResponseBody

    public Items queryItemsById4Rest(@PathVariable("itemsId") Integerid){

       returnservice.queryItemsById(id);

    }

    // 参数名相同的格式

    @RequestMapping("/queryItemsById/{id}")

    @ResponseBody

    public Items queryItemsById4Rest(@PathVariable Integerid){

       returnservice.queryItemsById(id);

    }

由于更改了在web.xml中的配置导致访问静态资源也会被拦截,所以需要在springmvc.xml中如下配置

    <!-- 配置静态资源处理器配置 -->

    <mvc:resourceslocation="/js/"mapping="/js/**"/>

    <mvc:resourceslocation="/css/"mapping="/css/**"/>

拦截器

Springmvc的拦截器主要是拦截处理器的

针对单个HandlerMapping配置(一般不使用)

<beanclass="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">

       <propertyname="interceptors">

              <list>

                     <refbean="handlerInterceptor1"/>

              </list>

       </property>

</bean>

<beanid="handlerInterceptor1"class="springmvc.intercapter.HandlerInterceptor1"/>

自定义拦截器

package com.itjava.ssm.controller.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

public class Interceptor1 implements HandlerInterceptor {

    // 使用时机:处理器执行之前

    // 使用场景:登录认证、权限验证

    // 返回值:true放行 false 不放行

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Objecthandler) throws Exception {

       System.out.println("Interceptor1...preHandle");

       return false;

    }

    // 使用时机:处理器执行时未返回之前

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler, ModelAndViewmodelAndView) throws Exception {

       // TODO Auto-generated method stub

       System.out.println("Interceptor1...postHandle");

    }

    // 使用时机:处理器执行之后

    // 使用场景:日志记录

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Objecthandler, Exception ex) throws Exception {

       // TODO Auto-generated method stub

       System.out.println("Interceptor1...afterCompletion");

    }

}

springmvc.xml

    <!-- 全局拦截器配置/**全部拦截 -->

    <mvc:interceptors>

       <mvc:interceptor>

           <mvc:mappingpath="/**"/>

           <beanclass="com.itjava.ssm.controller.interceptor.Interceptor1"></bean>

       </mvc:interceptor>

       <mvc:interceptor>

           <mvc:mappingpath="/**"/>

           <beanclass="com.itjava.ssm.controller.interceptor.Interceptor2"></bean>

       </mvc:interceptor>

    </mvc:interceptors>

<mvc:interceptor>

   <mvc:mappingpath="/manage/**"/>

   <mvc:exclude-mappingpath="/manage/goLogin.*"/>

   <mvc:exclude-mappingpath="/manage/login.*"/>

   <mvc:exclude-mappingpath="/manage/logout.*"/>

   <beanclass="com.xx.ManageInterceptor"/>

</mvc:interceptor>

拦截器测试:1在前先执行,2在后后执行

1放行,2放行

HandlerIntercepter1...preHandle

HandlerIntercepter2...preHandle

 

HandlerIntercepter2...postHandle

HandlerIntercepter1...postHandle

 

HandlerIntercepter2...afterCompletion

HandlerIntercepter1...afterCompletion

1放行,2不放行

HandlerIntercepter1...preHandle

HandlerIntercepter2...preHandle

 

HandlerIntercepter1...afterCompletion

1不放行,2不放行

HandlerIntercepter1...preHandle

 

 

0 0
原创粉丝点击