码迷,mamicode.com
首页 > 编程语言 > 详细

SpringMVC

时间:2018-01-10 13:52:46      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:转换器   图片   tis   ssi   targe   虚拟目录   mss   simple   定义   

技术分享图片

技术分享图片

SpringMVC

01.SpringMVC架构

技术分享图片

02.spring入门程序

程序执行步骤:

Tomcat启动-->加载web.xml-->加载web.xml中的servlet-->加载SpringMvc.xml配置文件-->

SpringMvc.xml(名称不固定)里面有:

<context:component-scan base-package="com.my.controller"></context:component-scan>

-->就会扫描这个包里面的所有类,然后就会加载含有@Controller注解的类,并将其加载到内存中变成对象

代码

Web.xml

<!-- springMVC前端控制器 -->
<servlet>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 制定springMVC核心配置文件的位置 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:SpringMvc.xml</param-value>
    </init-param>
    <!-- tomcat启动的时候加载这个servlet,第一个启动 -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springMvc</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>

SpringMvc.xml:里面有组件的配置信息

SpringMVC三大组件:

处理映射器:制定url到指定方法的映射

处理器适配器:根据不同的Handler找到不同的处理器适配器去执行Handler

视图解析器:根据不同的视图去解析(视图可以是jsppdfwordfreeMark

<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 
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://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        
        <!-- 配置@Controller注解扫描 -->
        <context:component-scan base-package="com.my.controller"></context:component-scan>
 
     <!-- 如果没有显示的配置处理器映射器和处理器适配那么springMvc会去默认的dispatcherServlet.properties中查找,
        对应的处理器映射器和处理器适配器去使用,这样每个请求都要扫描一次他的默认配置文件,效率非常低,会降低访问速度,所以要显示的配置处理器映射器和
        处理器适配器 -->
        <!-- 注解形式的处理器映射器 -->
<!--         <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean> -->
        <!-- 注解形式的处理器适配器 -->
<!--         <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean> -->
        
        <!-- 配置最新版的注解的处理器映射器 -->
<!--         <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> -->
        <!-- 配置最新版的注解的处理器适配器 -->
<!--         <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean> -->
 
<!-- 注解驱动:(与注解无关)
作用:替我们自动配置最新版的注解的处理器映射器和处理器适配器
 -->
<mvc:annotation-driven></mvc:annotation-driven>

<!-- 配置视图解析器 
作用:在controller中指定页面路径的时候就不用写页面的完整路径名称了,可以直接写页面去掉扩展名的名称
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 真正的页面路径 =  前缀 + 去掉后缀名的页面名称 + 后缀 -->
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>

Handler层代码

@Controller
public class ItemsController {
//指定URL到请求方法的映射
@RequestMapping("/list")
public ModelAndView itemsList() throws Exception{
        List<Items> itemList = new ArrayList<Items>();
        
        //商品列表
        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);
        
        //模型和视图
        //model模型: 模型对象中存放了返回给页面的数据
        //view视图: 视图对象中指定了返回的页面的位置
        ModelAndView modelAndView = new ModelAndView();
        
        //将返回给页面的数据放入模型和视图对象中
        modelAndView.addObject("itemList", itemList);
        
        //指定返回的页面位置,"itemList"是页面取数据的变量
        modelAndView.setViewName("itemList");
        
        return modelAndView;
    
    }
}

03.ssm整合(list功能)

1)Dao层

    pojo和映射文件以及接口使用逆向工程生成

    SqlMapConfig.xml   mybatis核心配置文件

    ApplicationContext-dao.xml 整合后springdao层的配置

    数据源

    会话工厂

    扫描Mapper

2)service层

    事务   ApplicationContext-trans.xml

    @Service注解扫描 ApplicationContext-service.xml

3)controller层

    SpringMvc.xml

    注解扫描:扫描@Controller注解

    注解驱动:替我们显示的配置了最新版的处理器映射器和处理器适配器

    视图解析器:显示的配置是为了在controller中不用每个方法都写页面的全路径

4)web.xml

    springMvc前端控制器配置

    spring监听

04-1.参数绑定

1. 默认支持类型(修改功能,modelrequeststringmodelview

Model比request强大一点

String和modelview都行,不过string代码少一点

注:mapper接口中的方法,如果是单表操作,则已经自动生成;多表操作需手动创建。

@Controller
public class ItemsController {
 
@Autowired
private ItemsService itmesService;
 
/**
 * springMvc中默认支持的参数类型:也就是说在controller方法中可以加入这些也可以不加,  加不加看自己需不需要,都行.
 *HttpServletRequest
 *HttpServletResponse
 *HttpSession
 *Model
 */
@RequestMapping("/itemEdit")
public String itemEdit(HttpServletRequest reuqest, 
 Model model) throws Exception{

    String idStr = reuqest.getParameter("id");
    Items items = itmesService.findItemsById(Integer.parseInt(idStr));
    
    //Model模型:模型中放入了返回给页面的数据
    //model底层其实就是用的request域来传递数据,但是对request域进行了扩展.
    model.addAttribute("item", items);
    
    //如果springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称
    return "editItem";
}
@Service
public class ItemsServiceImpl implements ItemsService {
 
    @Autowired
    private ItemsMapper itemsMapper;
     
    @Override
    public Items findItemsById(Integer id) throws Exception {
        Items items = itemsMapper.selectByPrimaryKey(id);
        return items;
    }
public interface ItemsMapper {
    Items selectByPrimaryKey(Integer id);

2. 基本类型和pojo类型

@Controller
public class ItemsController {
 
    @Autowired
    private ItemsService itmesService;
    //springMvc可以直接接收基本数据类型,包括string.spirngMvc可以帮你自动进行类型转换.
    //controller方法接收的参数的变量名称必须要等于页面上input框的name属性值
    //public String update(Integer id, String name, Float price, String detail) throws Exception{
    
        //spirngMvc可以直接接收pojo类型:要求页面上input框的name属性名称必须等于pojo的属性名称
        @RequestMapping("/updateitem")
        public String update(Items items) throws Exception{
        itmesService.updateItems(items);
        
        return "success";
    }
@Service
public class ItemsServiceImpl implements ItemsService {
    @Autowired
    private ItemsMapper itemsMapper;
    @Override
    public void updateItems(Items items) throws Exception {
        itemsMapper.updateByPrimaryKeyWithBLOBs(items);
    }
}
int updateByPrimaryKeyWithBLOBs(Items record);

3. 接收vo类型

public class QueryVo {
//商品对象
private Items items;
@Controller
public class ItemsController {
    @Autowired
    private ItemsService itmesService;
    //如果Controller中接收的是Vo,那么页面上input框的name属性值要等于vo的属性.属性.属性.....
    @RequestMapping("/search")
    public String search(QueryVo vo) throws Exception{
        System.out.println(vo);
        return "";
    }
}

4. 自定义类型转换器

当从界面传过来date类型的时候,使用pojo接收会报错,因为springmvc只会转换基本数据类型;对于其他类型,则需要自定义类型转换器。

具体操作:

01.先新建一个转换器类

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/**
 * S - source:源
 * T - target:目标
 * @author zj
 *
 */
public class CustomGlobalStrToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(source);
            return date;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

02.在springmvc配置文件中配置

<!-- 注解驱动:
      替我们显示的配置了最新版的注解的处理器映射器和处理器适配器 -->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置自定义转换器 
注意: 一定要将自定义的转换器配置到注解驱动上
-->
<bean id="conversionService"
    class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <!-- 指定自定义转换器的全路径名称 -->
            <bean class="cn.itheima.controller.converter.CustomGlobalStrToDateConverter"/>
        </set>
    </property>
</bean>

注意: 一定要将自定义的转换器配置到注解驱动上,因为会被处理器适配器去识别,进行转换

5. 高级参数绑定

数组:

页面

<form action="${pageContext.request.contextPath }/updateAll.action" method="post">
    <table width="100%" border=1>
        <tr>
            <td><input type="submit" value="批量修改"/></td>
        </tr>
    </table>
    商品列表:
    <table width="100%" border=1>
        <tr>
            <td></td>
            <td>商品名称</td>
            <td>商品价格</td>
            <td>生产日期</td>
            <td>商品描述</td>
            <td>操作</td>
        </tr>
        <c:forEach items="${itemList }" var="item" varStatus="status">
            <tr>
                <!-- name属性名称要等于vo中的接收的属性名 -->
                <!-- 如果批量删除,可以用List<pojo>来接收,页面上input框的name属性值= vo中接收的集合属性名称+[list的下标]+.+list泛型的属性名称 -->
                <td>
                    <input type="checkbox" name="ids" value="${item.id }"/>
                </td>
                <td>${item.name }</td>
                <td>${item.price }</td>
                <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
                <td>${item.detail }</td>
            </tr>
        </c:forEach>
         
    </table>
</form>
@RequestMapping("/delAll")
//会将多选框中的id放入vo类中,ids数组中
public String delAll(QueryVo vo) throws Exception{
    //如果批量删除,一堆input复选框,那么可以提交数组.(只有input复选框被选中的时候才能提交)
    System.out.println(vo);
    return "";
}
public class QueryVo {
//商品对象
private Items items;
//订单对象...
//用户对象....
 
//批量删除使用
private Integer[] ids;
集合:

页面:

<form action="${pageContext.request.contextPath }/updateAll.action" method="post">
    查询条件:
    <table width="100%" border=1>
        <tr>
        <!-- 如果Controller中接收的是Vo,那么页面上input框的name属性值要等于vo的属性.属性.属性..... -->
        <td>商品名称:<input type="text" name="items.name"/></td>
        <td>商品价格:<input type="text" name="items.price"/></td>
        <td><input type="submit" value="批量修改"/></td>
        </tr>
    </table>
    商品列表:
    <table width="100%" border=1>
        <tr>
            <td></td>
            <td>商品名称</td>
            <td>商品价格</td>
            <td>生产日期</td>
            <td>商品描述</td>
            <td>操作</td>
        </tr>
        <c:forEach items="${itemList }" var="item" varStatus="status">
            <tr>
            <!-- name属性名称要等于vo中的接收的属性名 -->
            <!-- 如果批量删除,可以用List<pojo>来接收,页面上input框的name属性值= vo中接收的集合属性名称+[list的下标]+.+list泛型的属性名称 -->
            <td>
                <input type="checkbox" name="ids" value="${item.id }"/>
                <input type="hidden" name="itemsList[${status.index }].id" value="${item.id }"/>
            </td>
            <td><input type="text" name="itemsList[${status.index }].name" value="${item.name }"/></td>
            <td><input type="text" name="itemsList[${status.index }].price" value="${item.price }"/></td>
            <td><input type="text" name="itemsList[${status.index }].createtime" 
               value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
            <td><input type="text" name="itemsList[${status.index }].detail" value="${item.detail }"/></td>
            
            <td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}">修改</a></td>
             
            </tr>
        </c:forEach>
         
    </table>
</form>
@RequestMapping("/updateAll")
public String updateAll(QueryVo vo) throws Exception{
    System.out.println(vo);
    return "";
}
public class QueryVo {
//商品对象
private Items items;
//订单对象...
//用户对象....
 
//批量删除使用
private Integer[] ids;
//批量修改使用
private List<Items> itemsList;

04-2.controller返回值

1. Void

返回void(使用它破坏了springMvc的结构,所以不建议使用)

可以使用request.setAttribut 来给页面返回数据

可以使用request.getRquestDispatcher().forward()来指定返回的页面

如果controller返回值为void则不走springMvc的组件,所以要写页面的完整路径名称

//返回数据
//request.setAttribute("", arg1);
//指定返回的页面(如果controller方法返回值为void,则不走springMvc组件,所以要写页面的完整路径名称)
//request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

2. StringModel(重定向和转发、相对路径和绝对路径)

String(推荐使用)

返回普通字符串,就是页面去掉扩展名的名称, 返回给页面数据通过Model来完成

返回的字符串以forward:开头为请求转发

返回的字符串以redirect:开头为重定向

重定向(model):

重定向,如果使用request,数据不能带的;但是如果使用model可以带上传递的数据

//重定向:浏览器中url发生改变,request域中的数据不可以带到重定向后的方法中
//model.addAttribute("id", items.getId());
//在springMvc中凡是以redirect:字符串开头的都为重定向
return "redirect:itemEdit/"+items.getId();
转发:
//请求转发:浏览器中url不发生改变,request域中的数据可以带到转发后的方法中
model.addAttribute("id", items.getId());
//spirngMvc中请求转发:返回的字符串以forward:开头的都是请求转发, 
//后面forward:itemEdit.action表示相对路径,相对路径就是相对于当前目录,当前为类上面指定的items目录.在当前目录下可以使用相对路径随意跳转到某个方法中
//后面forward:/itemEdit.action路径中以斜杠开头的为绝对路径,绝对路径从项目名后面开始算
return "forward:/items/itemEdit.action";

3. ModelAndView

ModelAndView
modelAndView.addObject("itemList", list); 指定返回页面的数据
modelAndView.setViewName("itemList");   指定返回的页面

4. 相对路径和绝对路径

相对路径:

相对于当前目录,也就是在当前类的目录下,这时候可以使用相对路径跳转

绝对路径:

从项目名后开始.

在springMvc中不管是forward还是redirect后面凡是以/开头的为绝对路径,不以/开头的为相对路径

例如:forward:/items/itemEdit.action 为绝对路径

forward:itemEdit.action为相对路径

05.乱码问题

Post

<!-- 配置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>

Get

01.修改Tomcat配置文件添加编码与工程编码一致:server.xml

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

02.对参数进行重编码

String username = new String(request.getParameter(username).getBytes(ISO8859-1),utf-8)

 

06.jsp传图片注意

<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->

<!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->

 

07.springmvcstruts2不同

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

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

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

 

08.@RequestMapping用法

1. URL路径映射

2. 窄化请求映射

3. 请求方法限定

技术分享图片

09.异常处理器

springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

异常处理思路

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

系统的dao、servicecontroller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

技术分享图片

自定义异常类

为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、servicedao抛出此类异常说明是系统预期处理的异常信息。

public class CustomException extends Exception {
 
    /** serialVersionUID*/
    private static final long serialVersionUID = -5212079010855161498L;
    
    public CustomException(String message){
        super(message);
        this.message = message;
    }
     
    //异常信息
    private String message;
     
    public String getMessage() {
        return message;
    }
     
    public void setMessage(String message) {
        this.message = message;
    }
}

自定义异常处理器

public class CustomExceptionResolver implements HandlerExceptionResolver {
 
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
    HttpServletResponse response, Object handler, Exception ex) {
     
        ex.printStackTrace();
         
        CustomException customException = null;
        
        //如果抛出的是系统自定义异常则直接转换
        if(ex instanceof CustomException){
            customException = (CustomException)ex;
        }else{
            //如果抛出的不是系统自定义异常则重新构造一个系统错误异常。
            customException = new CustomException("系统错误,请与系统管理 员联系!");
        }
        
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", customException.getMessage());
        modelAndView.setViewName("error");
         
        return modelAndView;
    }
 
}

错误页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>错误页面</title>
         
    </head>
    <body>
        您的操作出现错误如下:<br/>
        ${message }
    </body>
 
</html>

异常处理器配置

在springmvc.xml中添加:

<!-- 异常处理器 -->
<bean id="handlerExceptionResolver" class="cn.itcast.ssm.controller.exceptionResolver.CustomExceptionResolver"/>

异常测试

修改商品信息,id输入错误提示商品信息不存在。

修改controller方法“editItem”,调用service查询商品信息,如果商品信息为空则抛出异常:

010.SpringMVC上传图片

1. 配置虚拟图片服务器

前提:

 环境基于Tomcat6.x系列实验, 其它版本的Tomcat虚拟目录配置可能略有不同

1. 进入Tomcat conf\Catalina\localhost

技术分享图片

2. 新建xxx.xml文件, 我这里命名为img.xml

技术分享图片

3. xml文件中配置如下内容:

<Context path="/img" reloadable="true" docBase="D:\img" />

技术分享图片

path : 浏览器访问目录, 与xml文件名必须一致

       docBase : 虚拟目录

4. Tomcatconf\web.xml文件中找到如下配置:

listings 修改成true

技术分享图片

5. 通过浏览器访问

      http://ip:端口号/虚拟目录, 如可以显示,虚拟目录配置成功

技术分享图片

2. 导包

CommonsMultipartResolver解析器依赖commons-fileuploadcommons-io,加入如下jar包:

技术分享图片

3. 配置解析器

在springmvc.xml

<!-- 文件上传 -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为5MB -->
    <property name="maxUploadSize">
        <value>5242880</value>
    </property>
</bean>

4. 页面

<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<form id="itemForm" action="${pageContext.request.contextPath }/items/updateitem" 
method="post" enctype="multipart/form-data">
    <%--  <form id="itemForm" action="${pageContext.request.contextPath }/items/updateitem.action" method="post"> --%>
    <input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
    <table width="100%" border=1>
        <tr>
            <td>商品名称</td>
            <td><input type="text" name="name" value="${item.name }" /></td>
        </tr>
        <tr>
            <td>商品价格</td>
            <td><input type="text" name="price" value="${item.price }" /></td>
        </tr>
        
        <tr>
            <td>商品生产日期</td>
            <td><input type="text" name="createtime"
        value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td>
        </tr>
        
        <tr>
            <td>商品图片</td>
            <td>
            <c:if test="${item.pic !=null}">
            <img src="/pic/${item.pic}" width=100 height=100/>
            <br/>
            </c:if>
            <input type="file"  name="pictureFile"/> 
            </td>
        </tr>
         
        <tr>
            <td>商品简介</td>
            <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
            </td>
           </tr>
            <tr>
            <td colspan="2" align="center"><input type="submit" value="提交" />
        </td>
        </tr>
    </table>
 
</form>

5. web层操作

@RequestMapping("/updateitem")
//pictureFile跟页面中”<input type="file"  name="pictureFile"/> ”的name值一样
public String update(MultipartFile pictureFile,Items items, Model model, HttpServletRequest request) throws Exception{
    //1. 获取图片完整名称
    String fileStr = pictureFile.getOriginalFilename();
     
    //2. 使用随机生成的字符串+源图片扩展名组成新的图片名称,防止图片重名
    String newfileName = UUID.randomUUID().toString() + fileStr.substring(fileStr.lastIndexOf("."));
     
    //3. 将图片保存到硬盘
    pictureFile.transferTo(new File("E:\\image\\" + newfileName));
     
    //4.将图片名称保存到数据库
    items.setPic(newfileName);
    itmesService.updateItems(items);
     
    return "redirect:itemEdit/"+items.getId();
}

011.json数交互

@RequestBody

作用:

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为jsonxml等格式的数据并绑定到controller方法的参数上。

List.action?id=1&name=zhangsan&age=12

 

本例子应用:

@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象

 

@ResponseBody

作用:

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

 

本例子应用:

@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端

请求json,响应json实现:

1. 环境准备

Springmvc默认用MappingJacksonHttpMessageConverterjson数据进行转换,需要加入jackson的包,如下:

技术分享图片

2. springmvc.xml配置

在注解适配器中加入messageConverters

<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
        </list>
    </property>
</bean>

注意:如果使用<mvc:annotation-driven /> 则不用定义上边的内容。

3. 页面

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
        <title>查询商品列表</title>
    </head>
    <body> 
        <script type="text/javascript">
        function sendJson(){
            //请求json响应json
            $.ajax({
                type:"post",
                url:"${pageContext.request.contextPath }/items/sendJson.action",
                contentType:"application/json;charset=utf-8",
                data:'{"name":"测试商品","price":99.9}',
                success:function(data){
                alert(data);
                }
            });
        
        }
        </script>
        <input type="button" value="senJson" onClick="sendJson()"/>
        <form action="${pageContext.request.contextPath }/updateAll.action" method="post">
            查询条件:
            <table width="100%" border=1>
                <tr>
                <!-- 如果Controller中接收的是Vo,那么页面上input框的name属性值要等于vo的属性.属性.属性..... -->
                <td>商品名称:<input type="text" name="items.name"/></td>
                <td>商品价格:<input type="text" name="items.price"/></td>
                <td><input type="submit" value="批量修改"/></td>
            </tr>
            </table>
            商品列表:
            <table width="100%" border=1>
            <tr>
                <td></td>
                <td>商品名称</td>
                <td>商品价格</td>
                <td>生产日期</td>
                <td>商品描述</td>
                <td>操作</td>
            </tr>
            <c:forEach items="${itemList }" var="item" varStatus="status">
                <tr>
                    <!-- name属性名称要等于vo中的接收的属性名 -->
                    <!-- 如果批量删除,可以用List<pojo>来接收,页面上input框的name属性值= vo中接收的集合属性名称+[list的下标]+.+list泛型的属性名称 -->
                    <td>
                    <input type="checkbox" name="ids" value="${item.id }"/>
                    <input type="hidden" name="itemsList[${status.index }].id" value="${item.id }"/>
                    </td>
                    <td><input type="text" name="itemsList[${status.index }].name" value="${item.name }"/></td>
                    <td><input type="text" name="itemsList[${status.index }].price" value="${item.price }"/></td>
                    <td><input type="text" name="itemsList[${status.index }].createtime" 
                       value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
                    <td><input type="text" name="itemsList[${status.index }].detail" value="${item.detail }"/></td>
                    
                    <td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}">修改</a></td>
                 
                </tr>
            </c:forEach>
             
            </table>
        </form>
    </body>
     
</html>

4. controller操作

//导入jackson的jar包在 controller的方法中可以使用@RequestBody,让spirngMvc将json格式字符串自动转换成java中的pojo
//页面json的key要等于java中pojo的属性名称
//controller方法返回pojo类型的对象并且用@ResponseBody注解,springMvc会自动将pojo对象转换成json格式字符串
@RequestMapping("/sendJson")
@ResponseBody
public Items json(@RequestBody Items items) throws Exception{
    System.out.println(items);
    return items;
}

012.restful

什么是restful

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

资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数

Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673

资源操作:使用putdeletepostget,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是postgetPutDelete几乎不使用。

需求

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

添加DispatcherServletrest配置(在web.xml

<!-- springmvc前端控制器 -->
  <servlet>
   <servlet-name>springMvc</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:SpringMvc.xml</param-value>
   </init-param>
   <!-- 在tomcat启动的时候就加载这个servlet -->
   <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
   <servlet-name>springMvc</servlet-name>
   <!-- 
   *.action    代表拦截后缀名为.action结尾的
   /    拦截所有但是不包括.jsp
   /*    拦截所有包括.jsp
    -->
   <url-pattern>/</url-pattern>
  </servlet-mapping>

URL 模板模式映射

@RequestMapping(value="/ viewItems/{id}")

{×××}占位符,请求的URL可以是/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。

@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。

技术分享图片

@RequestMapping("/viewItems/{id}") 
public @ResponseBody viewItems(@PathVariable("id") String id,Model model) throws Exception{
    //方法中使用@PathVariable获取useried的值,使用model传回页面
    //调用 service查询商品信息
    ItemsCustom itemsCustom = itemsService.findItemsById(id);
    return itemsCustom;
}

如果RequestMapping中表示为"/viewItems/{id}"id和形参名称一致,@PathVariable不用指定名称。

有多个加多个占位符就好

 

商品查询的controller方法也改为rest实现:

技术分享图片

// 查询商品列表
@RequestMapping("/queryItem")
public ModelAndView queryItem() throws Exception {
    // 商品列表
    List<Items> itemsList = itemService.findItemsList(null);
     
    // 创建modelAndView准备填充数据、设置视图
    ModelAndView modelAndView = new ModelAndView();
     
    // 填充数据
    modelAndView.addObject("itemsList", itemsList);
    // 视图
    modelAndView.setViewName("item/itemsList");
     
    return modelAndView;
}

静态资源访问<mvc:resources>

如果在DispatcherServlet中设置url-pattern/则必须对静态资源进行访问处理。

spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。

如下是对js文件访问配置:

<mvc:resources location="/js/" mapping="/js/**"/>

 

013.拦截器

1. 拦截器基础

public class Interceptor1 implements HandlerInterceptor {
 
    //执行时机:controller已经执行,modelAndview已经返回
    //使用场景: 记录操作日志,记录登录用户的ip,时间等.
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    throws Exception {
        System.out.println("======Interceptor1=======afterCompletion========");
    }
     
    //执行时机:Controller方法已经执行,ModelAndView没有返回
    //使用场景: 可以在此方法中设置全局的数据处理业务
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    throws Exception {
        System.out.println("======Interceptor1=======postHandle========");
     
    }
     
    //返回布尔值:如果返回true放行,返回false则被拦截住
    //执行时机:controller方法没有被执行,ModelAndView没有被返回
    //使用场景: 权限验证
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("======Interceptor1=======preHandle========");
        return true;
    }
 
}
<!-- 配置拦截器 -->
<mvc:interceptors>
    <!-- 多个拦截器的执行顺序等于springMvc.xml中的配置顺序 -->
    <!--   <mvc:interceptor> -->
    <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
    <!--    <mvc:mapping path="/**"/> -->
    <!-- 指定拦截器的位置 -->
    <!--    <bean class="cn.itheima.interceptor.Interceptor1"></bean> -->
    <!--   </mvc:interceptor> -->
    
    <!--   <mvc:interceptor> -->
    <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
    <!--    <mvc:mapping path="/**"/> -->
    <!-- 指定拦截器的位置 -->
    <!--    <bean class="cn.itheima.interceptor.Interceptor2"></bean> -->
    <!--   </mvc:interceptor> -->
    
    <mvc:interceptor>
        <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
        <mvc:mapping path="/**"/>
        <!-- 指定拦截器的位置 -->
        <bean class="cn.itheima.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

针对某种mapping配置拦截器

<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors">
    <list>
    <ref bean="handlerInterceptor1"/>
    <ref bean="handlerInterceptor2"/>
    </list>
    </property>
</bean>
<bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
<bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

针对所有mapping配置全局拦截器

<!--拦截器 -->
<mvc:interceptors>
    <!--多个拦截器,顺序执行 -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.springmvc.filter.HandlerInterceptor1"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="cn.itcast.springmvc.filter.HandlerInterceptor2"></bean>
        </mvc:interceptor>
</mvc:interceptors>

2. 实现登录拦截过程

技术分享图片




SpringMVC

标签:转换器   图片   tis   ssi   targe   虚拟目录   mss   simple   定义   

原文地址:http://blog.51cto.com/qinbin/2059370

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!