springmvc系列第2篇:整合mybatis

前言

sprring可以将各层进行整合
1.通过spring来管理持久层的mapper(相当于dao接口)
2.通过spring来管理业务层的service,service中可以调用mapper接口,也可以进行事物控制。
3.通过spring来管理表现层的Handler(相当于controller),Handler可以调用service接口。
总结:mapper、service、Handler都是JavaBean,所以可以通过spring的IOC容器进行管理

一、springmvc和mybatis整合思路

1.整合持久层Dao

第一步:整合dao层
mybatis和spring的整合,通过spring来管理mapper接口
使用mapper的扫描器自动扫描mapper接口在spring容器中进行注册
mybatis-spring-1.3.1进行整合
sqlMapperConfig.xml是mybatis自己的配置文件,在config/mybatis下进行如下配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置mapper
本来要配置mappers,因为我们要使用spring和mybatis的整合包进行mapper的扫描,所以不需要配置
加载mapper,必须遵循:mapper.xml和mapper.java文件同名写在一个目录
-->
<!-- <mappers>
    </mappers>-->

 <!--配置别名-->
    <typeAliases>
        <!--批量扫描别名-->
        <package name="com.ming.po"/>
    </typeAliases>
   <!--全局的setting配置,根据需要添加-->
</configuration>

配置spring整合的applicationContext-dao.xml
配置spring和整合的如:
数据源、sqlSesesionFactory、mapper扫描器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--告知spring要扫描的bao-->
    <context:component-scan base-package="com.ming"></context:component-scan>
    <!--加载db.properties文件内容,key命名具有一定的特殊规则-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--配置数据源dbcp-->
    <bean id="datatSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="maxActive" value="30"/>
        <property name="maxIdle" value="5"/>
    </bean>
    <!--配置sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--数据源-->
        <property name="dataSource" ref="datatSource"></property>
        <!--加载mybatis的全局配置文件-->
        <property name="configLocation" value="classpath:mybatis/sqlMapperConfig.xml"></property>
    </bean>
    <!--mapper的扫描器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--mapper扫描的包路径,如果需要扫描多个包,中间使用半角的逗号隔开-->
        <property name="basePackage" value="com.ming.mapper"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>
</beans>

编写mapper文件
逆向工程生成po类和mapper(单表的crud)

2.整合业务层Service

第二步:整合service层
通过spring来管理我们的service接口
使用注解@service和xml声明式配置的方式在spring的IOC容器中进行注册
实现事物控制,一般在service业务层。
编写业务层代码,通过xml或注解的方式将service层注入到IOC容器中,创建apllictionContext-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--配事物管理器-->
    <import resource="applicationContext-dao.xml"></import>
    <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="save*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="update*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="delete*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false"></tx:method>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!--配置aop-->
    <aop:config>
        <aop:pointcut id="tx_poincut" expression="execution(* com.ming.service.imple.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="tx_poincut"></aop:advisor>
    </aop:config>
</beans>

3.整合表现层springmvc

由于springmvc是spring的模块,所以spring和springmvc不需要通过中间层进行整合
1.创建springmvc.xml文件,配置前端控制器,处理器适配器,映射器,视图解析器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/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/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--告知spring扫描的包-->
    <context:component-scan base-package="com.ming.controller"></context:component-scan>

    <!--注解的映射器-->
    <!--   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>-->
    <!-- 注解的适配器-->
    <!--  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>-->
    <!--使用mvc:annotation-driven的注解驱动可以代替上面的注解适配器和映射器
    默认加载了很多的参数绑定方法,比如json的转换解析器就默认加载了
    实际开发中使用mvc:annotation-driven注解
    -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!--视图解析器
    解析jsp视图,默认使用jstl标签,classpath下面有jstl的包
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

2.配置前端控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--    <context-param>-->
<!--        <param-name>contextConfigLocation</param-name>-->
<!--        <param-value>/WEB-INF/applicationContext.xml</param-value>-->
<!--    </context-param>-->
<!--    <listener>-->
<!--        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>-->
<!--    </listener>-->

    <!--配置srpingmvc前端控制器-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation配置springmvc加载的配置文件(处理器映射器,适配器等)
             如果不配置contextConfigLocation,默认加载的是web/web-inf下面的/servlet名称-sevrlet.xml(dispatcher-servlet.xml)
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--配置servlet映射路径-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.action</url-pattern>
        <!--url-pattern配置方式
        第一种:*.action访问以.action结尾的由DispactherServlet解析
        第二种:/所有访问的地址都由DispatcherServlet解析(对于静态文件图片、js、jsp的解析,我们需要配置不让DispactherServlet解析)
        使用此种方法可以实现ResultFUl风格的url
        第三种:/* 这种配置不对,使用这种配置,最终要转发到一个jsp页面,仍然由DispactherServlet解析jsp地址,不能根据jsp页面找到Handler会报错
        -->
    </servlet-mapping>

</web-app>

二、参数绑定

1.RequestMapping注解

作用:定义controller方法对应的url,进行处理器映射使用
限制http请求方法:
@RequestMapping(value = “/editItems”,method = {RequestMethod.GET,RequestMethod.POST})
解决post、get乱码
post乱码在web.xml添加filter:

 <!--解决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乱码:
第一种在Tomcat的配置文件server.xml中修改:
<Connector port=“8080” protocol="HTTP/1.1"connectionTimeout=“20000” redirectPort=“8443” URIEncoding=“UTF-8”/>
第二种:对参数进行重新编码:
String name = new String(request.getParameter(“name”).getBytes(“ISO8859-1”),“utf-8”);
ISO8859-1Tomcat默认的编码,需要将Tomcat编码后的内容按utf-8编码

2.参数绑定

1.spring参数绑定过程
从客户端请求key/value的数据,经过参数绑定,将key/value的数据绑定到你controller的形参上。
springmvc接受页面提交的数据是通过方法的形参来接受。而不是在controller类定义成员变量来接受

2.参数绑定默认支持的类型
HttpservletRequest:通过request获取对象请求信息
HttpServletResponse:通过response处理响应信息
HttpSession:获取session中存放的信息
Model、ModelMap:model是一个接口,modelMap是一个接口实现。作用是将模型数据填充到request域
3.简单类型绑定
整形、字符串、float、double、boolean
@RequestParam用于简单类型的参数绑定
如果不使用@RequestParam,要求Request传入的参数名称和Controller方法形参的名称一致,才可以绑定成功
required = true 必须传参,defaultValue默认值
4.POJO
1.简单pojo
页面input中的name属性名称和controller中pojo形参的属性名称一致,将页面中的数据绑定到pojo
2.包装pojo
页面的参数和controller方法的形参定义
页面参数:< input type=“text” name=“itemsCustom.name”>
controller方法的形参:ItemsQueryVo itemsQueryVo(itemsCustom是Vo的包装类)
itemsCustom和包装类中的pojo类的属性一致
5.自定义参数绑定
对于controller形参中的pojo的对象、如果属性有日期类型,需要自定义参数绑定
将请求日期数据串转换成日期类型,要转换的日期类型和pojo中的日期属性类型保持一致
参数绑定组件也叫转换器Converter
springmvc.xml

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!--自定义参数绑定-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <!--转换器-->
    <property name="converters">
        <list>
            <!--日期类型的转换-->
           <bean class="com.ming.controller.converter.DateConverter"></bean>
        </list>
    </property>
</bean>

DateConverter.java

package com.ming.controller.converter;

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义参数绑定-日期转换器
 */
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

6.集合类
1.数组的绑定
前端传的input中name属性名称和后端controller中的public String deleteItemsBatch(Integer[] items_id)形参名称items_id保持一致,传入的值是c:forEach 循环后的input中的value=’${items.id}’,根据主键id删除。
2.list绑定
controller:使用list来接受页面提交的批量数据,通过包装pojo来接收,在包装类vo或pojo中定义list < pojo>属性
页面:

@RequestMapping("/updateItemsBatch")
public String updateItemsBatch(ItemsQueryVo itemsQueryVo) {
    itemService.updateBatchItems(itemsQueryVo.getItemsCustomList());
    return "forward:/items/queryItems.action";
}
<input type="text" name="itemsCustomList[${status.index }].name" value="${item.name}"/>

itemsCustomList对应包装类(ItemsQueryVo)pojo的List类型的属性名称,status.index 是下标从0开始,name对应了包装类pojo中List属性的pojo包装类的属性名称
3.map的绑定
也是通过在包装类pojo中定义map类型属性

三、validation校验

1.服务端校验

项目中,通常在页面中校验。对于安全性要求要在服务端校验。
服务端校验:
控制层:controller校验页面请求的参数合法性,在服务端控制层校验,不区分客户端类型(浏览器,手机客户端)
业务层校验(使用比较多):主要校验关键业务参数,仅限service层中使用的参数
持久层:一般不校验。
springmvc校验使用的是hibernate的一个框架validation校验(和hibernate没有关系)
需要的jar:validation-api-1.0.0.GA.jar、javassist-3.21.0-GA.jar、jboss-logging-3.1.0.CR2.jar
springmvc.xml处理器适配器中引用validator:

 <mvc:annotation-driven conversion-service="conversionService" validator="validation"></mvc:annotation-driven>
    <!--自定义参数绑定-->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!--转换器-->
        <property name="converters">
            <list>
                <!--日期类型的转换-->
               <bean class="com.ming.controller.converter.DateConverter"></bean>
            </list>
        </property>
    </bean>
    <!--校验器-->
    <bean id="validation" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <!--HibernateValidator校验器-->
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
        <!--指定校验使用的资源文件,如果不指定则默认使用classpath下的ValidationMessages.properties-->
        <property name="validationMessageSource" ref="messageSource"></property>
    </bean>
    <!--校验错误信息配置文件-->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!--资源文件名-->
        <property name="basenames">
            <list>
                <value>classpath:CustomValidationMessages</value>
            </list>
        </property>
        <!--资源文件编码格式-->
        <property name="fileEncodings" value="utf-8"></property>
        <!--对资源文件内容缓存时间,单位秒-->
        <property name="cacheSeconds" value="120"></property>
    </bean>

在pojo中添加校验规则

public class Items {
    private Integer id;
    //校验名称在1-30个字符中间
    //message是提示错误的信息
    @Size(min=1,max = 30,message ="{items.name.length.error}" )
    private String name;

    private Float price;

    private String pic;
    @NotNull(message = "{items.createtime.isnull}")
    private Date createtime;
}

配置CustomValidationMessages.properties错误校验的提示信息如下

#添加错误校验的提示信息
items.name.length.error=请输入130个字符的名称
items.createtime.isnull=请输入商品的生成日期

controller中需要校验的形参pojo前边添加@Validated,在后边跟着添加BindingResult用于接收校验错误信息
注意@Validated和BindingResult是配对出现的,并且顺序是固定的( @Validated ItemsCustom itemsCustom, BindingResult bindingResult 一前一后出现的)

2.分组校验

自定义接口分组group
在校验的pojo属性上@Size(min=1,max = 30,message ="{items.name.length.error}",groups={自定义的分组接口group.class} )
controller形参上添加,@Validated(value = {自定义的分组接口group.class}

四、数据回显

1.数据回显

数据提交后,如果出现错误,将刚才提交的数据又回显到刚提交的页面

2.pojo数据回显

第一种:springmvc可以默认对pojo的数据回显。pojo数据传入controller后,springmvc会自动将pojo数据放到request域,key等于pojo的类名首字母小写。
controller方法形参上面添加@ModelAttribute可以指定pojo回显到页面在rquest中的key来进行数据回显
第二种:@ModelAttribute将方法的返回值传到页面

    @ModelAttribute("itemsType")
    public Map<String,Object> itemsType(){
        Map<String,Object> itemsType = new HashMap<>();
        itemsType.put("办公","电脑");
        itemsType.put("娱乐","手机");
        return  itemsType;
    }
    //页面
  <select name="itemsType">
     <c:forEach items="${itemsType}" var="item">
         <option value="${item.key}">${item.value}</option>
     </c:forEach>
 </select>

第三种最简单的回显:可以使用model.addAttribute(),简单数据类型的回显也可以使用 model.addAttribute()方法

五、全局异常处理

springmvc提供全局的异常处理器(一个系统只有一个异常处理器)进行统一的异常处理

1.自定义异常类

对不同的异常类型定义异常类,继承Exception

/**
 * 系统自定义异常类
 */
public class CustomException extends Exception{

    //异常信息
    private String messsage;

    public CustomException(String message) {
        super(message);
        this.messsage = messsage;
    }

    public String getMesssage() {
        return messsage;
    }

    public void setMesssage(String messsage) {
        this.messsage = messsage;
    }
}

2.全局异常处理器

系统遇到异常,在程序中手动抛出,dao抛出给service抛出给controller最后抛出给DispatcherServlet,最后前端控制器调用异常处理器。
全局异常处理器的处理思路:
解析出异常类型
如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
如果该异常类型不是系统自定义的异常,构造一个自定义异常类型(信息为未知错误)
springmvc提供了HandlerExceptionResolver接口

package com.ming.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理器
 */
public class CustomExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception ex) {
        //Object handler就是处理器适配器最终要执行的handler
        // 解析出异常类型
        //如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
       /* String message = null;
        if(ex instanceof CustomException){
            message = ((CustomException)ex).getMessage();
        }else{
            // 如果该异常类型不是系统自定义的异常,构造一个自定义异常类型(信息为未知错误)
            message="未知错误";
        }*/
        CustomException customException = null;
        if (ex instanceof CustomException) {
            customException = (CustomException) ex;
        } else {
            customException = new CustomException("未知错误");
        }
        String message = customException.getMesssage();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", message);
        //指向错误页面
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

最后在springmvc.xml配置

    <!--全局异常处理器-->
    <bean class="com.ming.exception.CustomExceptionResolver"/>

六、上传图片

1.springmvc对多部件类型进行解析

在jsp页面的form表单中提交enctype="multipart/form-data"的数据时,springmvc对multipart类型的数据进行解析。
必须在springmvc.xml中配置multipart类型的解析器

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

2.创建图片虚拟目录存储图片

企业正常会有图片服务器来存储图片
1.修改Tomcat的配置文件conf/server.xml:
<context path="/springmvc_img" docBase="E:\javacode\idea_workspace\springmvc_img" reloadable="true" crossContext="true"/>
2.在idea\eclipse中配置Tomcat的虚拟目录
重新启动Tomcat部署后就可以直接访问http://127.0.0.1:8080/springmvc_img/psb.jpg下面的图片
注意:在图片虚拟目录中,一定要将图片目录分级创建,提高I/O性能,一般采用按日期分级创建。

上传的jar:commons-fileupload-1.3.1.jar、commons-io-2.3.jar

 @RequestMapping(value = "/editItemsSubmit", method = {RequestMethod.POST})
    public String editItemsSubmit(HttpServletRequest request, @RequestParam(value = "id") Integer id, ItemsCustom itemsCustom,
                                  MultipartFile multipartFile) throws Exception {
        //图片原名称
        String file_name = multipartFile.getOriginalFilename();
        //上传图片
        if (multipartFile != null && file_name != null && file_name.length() > 0) {
            //存储图片的物理路径
            String img_path = "E:\\javacode\\idea_workspace\\springmvc_img\\";
            //新图片名称
            String new_file_name = UUID.randomUUID() + file_name.substring(file_name.lastIndexOf("."));
            //创建文件实例
            File file = new File(img_path + new_file_name);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
                System.out.println("创建目录:" + file);
            }
            // 写入文件
            multipartFile.transferTo(file);
            itemsCustom.setPic(new_file_name);
        }
        itemService.updateItemsById(id, itemsCustom);
        //重定向
        //return  "redirect:/items/queryItems.action";
        //转发
        return "forward:/items/queryItems.action";
    }

七、Json数据交互

为什么要进行json数据交互?
json数据格式在我们接口调用以及html页面中比较常用,因为json格式比较简单和解析比较方便。

1. @RequestBody

将Json串转换成Java对象

2. @ResponseBody

@ResponseBody用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读取到的内容转为json、xml等格式的数据绑定到controller方法的参数上。
将Java对象转换成json串输出

3.配置Json转换器

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

在注解适配器中加入messageConverters

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

注意:使用了<mvc:annotation-driven >注解驱动的标签不用配置Json转换器
测试代码:

package com.ming.controller;
import com.ming.po.ItemsCustom;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * json交互测试
 */
@Controller
@RequestMapping("/jsonTest")
public class JsonTestController {
    /**
     *  请求json串(商品信息),响应输出json(商品信息)
     *  RequestBody将请求的商品信息json串转出Java对象itemsCustom
     *  ResponseBody将Java对象itemsCustom转换成json输出
     * @return
     */
    @RequestMapping(value = "/requestJson")
    public @ResponseBody ItemsCustom requestJson(@RequestBody ItemsCustom itemsCustom){
        //ResponseBody将Java对象itemsCustom转出json输出
        return itemsCustom;
    }
    /**
     * 请求kev/value输出json
     * @param itemsCustom
     * @return
     */
    @RequestMapping(value = "/responseJson")
    public @ResponseBody ItemsCustom responseJson(ItemsCustom itemsCustom){
        //ResponseBody将Java对象itemsCustom转出json输出
        return itemsCustom;
    }
}

直接将jsonTest.jsp放在web目录下:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" isELIgnored="false"%>
<%@ taglib  prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" >
    <title>json交互的测试</title>
  <%-- <%
        String path = request.getContextPath();
        String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    <script type="text/javascript" src="<%=basePath%>js/jquery-3.1.1.min.js"></script>--%>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.1.1.min.js"></script>
    <script type="text/javascript">
        //请求的是json,输出的是json
        function requestJson() {
            $.ajax({
                type: "post",
                url: "${pageContext.request.contextPath}/jsonTest/requestJson.action",
                contentType:"application/json;charset=UTF-8",
                data: JSON.stringify({"name":"手机","price":999}),
                //data:' {"name":"手机","price":999}',
                success: function(data){
                    //返回json
                    alert( "data: " + data );
                },
                error:function (error) {
                    alert( "error: " + error );
                }
            });
        }
        //请求的是key/value,输出的是json
        function  responseJson() {
            $.ajax({
                type: "post",
                //请求的是key/value不需要指定contentType,默认就是
                //contentType:"application/json;charset=UTF-8",
                url: "${pageContext.request.contextPath}/jsonTest/responseJson.action",
                data: "name=手机&price=999",
                success: function(data){
                    //返回json
                    alert( "data: " + data );
                },
                error:function (error) {
                    alert( "error: " + error );
                }
            });
        }

    </script>
</head>
<body>
<input type="button" onclick="requestJson()" value="请求的是json,输出的是json"/>
<input type="button" onclick="responseJson()" value="请求的是key/value,输出的是json"/>
</body>
</html>

八、支持RestFul风格

1.什么是RestFul

Restful是一种互联网软件架构,其实是一种开发理念,对http很好的诠释。
四种基本操作:Get用来获取资源,POST用来新建资源(也可以用来更新资源,做修改数据操作,put用来更新资源,Delete用来删除资源

2.url进行规范

1、url进行规范
非restful的url:http://localhost:8080/queryItems.action?id=001&type=1
restful风格url:http://localhost:8080/queryItems/001
特点:url简洁,将参数通过url传到服务端
2、http的方法进行规范
不管删除,添加,更新,使用的url是一致的,如果进行删除操作,需要设置http的方法为delete。
后台的controller方法:需要判断http方法。如果是delete,要进行删除,如果是post执行添加。
一般只用于对url的规范,因为一个方法中可能有多个操作,需要进行方法逻辑的判断,比较麻烦
3、对http的contenttype进行规范
请求时指定contentType,比如设置json数据格式

    /**
     * 根据id查询商品,使用RESTful风格
     * mapping中的id将这个url位置的参数传到PathVariable注解指定的名称中
     * @param id
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/itemsView/{id}")
    public ItemsCustom itemsView(@PathVariable("id") Integer id) throws Exception {
       ItemsCustom itemsCustom = itemService.findItemsById(id);
       return itemsCustom;
    }

RestFul前端控制器

    <!--配置rest前端控制器-->
    <servlet>
        <servlet-name>springmvc_rest</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--配置servlet映射路径-->
    <servlet-mapping>
        <servlet-name>springmvc_rest</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

Spring+SpringMVC+Mybatis整合 pom示例

<!-- SpringMVC,Spring -->
<dependencies>
    <!-- Spring mvc -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring Jdbc -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring面向切面编程 -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>

    <!-- Spring测试 -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.3.7.RELEASE</version>
        <scope>test</scope>
    </dependency>

    <!-- Mybatis -->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.2</version>
    </dependency>

    <!-- 分页插件 -->
    <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.0.0</version>
    </dependency>

    <!-- Mybatis Spring整合适配包 -->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
    <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-core</artifactId>
        <version>1.3.7</version>
    </dependency>


    <!-- 数据库连接池 、驱动 -->
    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.41</version>
    </dependency>

    <!-- jstl servlet-api junit -->
    <!-- https://mvnrepository.com/artifact/jstl/jstl -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>


    <!-- 单元测试 -->
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>

    <!-- 日志技术 log4j -->
    <!-- 引入log4j日志包 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>

    <!-- 处理json -->
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9.3</version>
    </dependency>

    <!-- JSR303 校验支持 -->
    <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.17.Final</version>
    </dependency>

</dependencies>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值