一、其他三种开发方式

方式一和方式二中的controller都需要实现其他类,侵入性太强,一般选择方式三、四开发

1.1 方式二

编写spring mvc配置文件:

  1. <!-- 方式二 -->
  2. <!-- 1.handlerMapping:处理器映射器 根据url找到对应的hanlder(servlet)处理请求 -->
  3. <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  4. <property name="mappings">
  5. <props>
  6. <prop key="/goods">goods</prop>
  7. </props>
  8. </property>
  9. </bean>
  10. <!-- 2.handleradapter:处理器适配器,用来调用handler的方法(处理请求)-->
  11. <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
  12. <!-- 3.视图解析器:将逻辑视图转换成物理视图 -->
  13. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
  14. <!-- 4.配置handler对应的url -->
  15. <bean id="goods" class="com.woniuxy.controller.GoodsController"></bean>

编写controller实现HttpRequestHandler接口:

  1. public class GoodsController implements HttpRequestHandler {
  2. @Override
  3. public void handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
  4. System.out.println("处理请求");
  5. }
  6. }

1.2 方式三(注解方式)

编写spring mvc配置文件:

  1. <!-- 方式三 -->
  2. <!-- 1.handlerMapper:处理器映射器 根据url找到对应的handler(servlet)处理请求 -->
  3. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
  4. <!-- 2.handleradapter:处理器适配器,用来调用handler的方法(处理请求) -->
  5. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
  6. <!-- 3.视图解析器:将逻辑视图转换成物理视图 -->
  7. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
  8. <!-- 4.扫描controller所在的包 -->
  9. <context:component-scan base-package="com.woniuxy.controller"></context:component-scan>

编写controller:

  1. @Controller //表示当前类用于处理请求 表示层相当于servlet
  2. @RequestMapping("/cart")
  3. public class CartController {
  4. @RequestMapping("/all")
  5. public void all() {
  6. System.out.println("查询购物车所有信息");
  7. }
  8. @RequestMapping("/del")
  9. public void del() {
  10. System.out.println("删除购物车信息");
  11. }
  12. }

1.3 方式四(注解方式+简化配置)

编写spring mvc配置文件:

  1. <!-- 方式四 -->
  2. <mvc:annotation-driven></mvc:annotation-driven>
  3. <!-- 3.视图解析器:将逻辑视图转换成物理视图 -->
  4. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
  5. <!-- 4.扫描controller所在的包 -->
  6. <context:component-scan base-package="com.woniuxy.controller"></context:component-scan>

controller与方式三一致

二、SpringMVC开发详解

2.1 返回值

2.1.1 返回void

所有处理请求的方法结束之后默认进行请求转发,如果返回值为void,则报404找不到页面

  1. @Controller //表示当前类用于处理请求
  2. @RequestMapping("/cart")
  3. public class CartController {
  4. @RequestMapping("/all")
  5. public void all() {
  6. System.out.println("查询购物车所有商品信息");
  7. }
  8. @RequestMapping("/del")
  9. public void del() {
  10. System.out.println("删除购物车信息");
  11. }
  12. }

2.1.2 返回String

返回值类型为String默认进行请求转发,如果要重定向则可以在返回值字符串前添加redirect

  1. //返回值为String 默认指的是跳转的url 默认采用请求转发
  2. @RequestMapping("/update")
  3. public String update() {
  4. System.out.println("修改购物车信息");
  5. return "/index.html";
  6. }
  7. //采用重定向
  8. @RequestMapping("/update2")
  9. public String update2() {
  10. System.out.println("修改购物车信息");
  11. return "redirect:/index.html";
  12. }

2.1.3 返回ModelAndView

返回值类型为ModelAndView,默认进行请求转发

  1. @RequestMapping("/add")
  2. public ModelAndView add() {
  3. ModelAndView modelAndView = new ModelAndView();
  4. modelAndView.addObject("name","lisi");
  5. modelAndView.setViewName("/user.jsp");
  6. return modelAndView;
  7. }

2.2 获取请求参数

2.2.1 获取单个参数

1.通过request获取前端传来的参数(与以前类似)

  1. @Controller
  2. @RequestMapping("/data")
  3. public class DataController {
  4. //1.单个数据
  5. @RequestMapping("/findById")
  6. public void findById(HttpServletRequest request) {
  7. System.out.println(request.getParameter("id"));
  8. }
  9. }

2.直接传入参数(SpringMVC进行过封装)

    //写法2
    //400错误 类型错误 传递参数无法转换成指定类型的参数
    //建议使用包装类,如Integer,无法转换则会自动设置为null,解决400错误是否出现的问题
    @RequestMapping("/findById2")
    public void findById2(Integer id) {
        System.out.println(id);
    }

3.通过@RequestParam指定接收哪个参数(常用),可以解决提交参数名和传入参数名不一致的问题

    //通过id删除
    //@RequestParam    从request中获取参数
    //    name:获取指定名字的参数
    //    required:必须给参数(不给参数会报400错误)
    @RequestMapping("/del")
    public void delById(@RequestParam(name="id",required=true,defaultValue="1001")int id) {
        System.out.println(id);
    }

2.2.2 获取多个参数

    //2.多个数据
    @RequestMapping("/login")
    public void login(String account,String pwd) {
        System.out.println(account+":"+pwd);
    }

    //更多数据:springmvc将数据自动封装成指定类型的对象
    @RequestMapping("/regist")
    public void regist(User user) {
        System.out.println(user);
    }

2.2.3 获取request、response等对象

如果想要在方法中获取request、response、session等对象,也可以在参数列表中直接写出来,Spring mvc会自动传入

    //request response
    @RequestMapping("/test")
    public void test(HttpServletRequest request,HttpServletResponse response) {
        String data = "{id:1001,name:'lisi'}";
        response.setContentType("application/json;charset=utf-8");
        try {
            response.getWriter().write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.3 返回JSON数据

2.3.1 导包

jackson-annotations-2.9.0.jar
jackson-core-2.9.5.jar
jackson-core-asl-1.9.13.jar
jackson-databind-2.9.5.jar
jackson-mapper-asl-1.9.13.jar

2.3.2 注解

在需要返回JSON数据的方法上添加@ResponseBody注解,该注解会自动设置contextType响应头

    @RequestMapping("/info")
    @ResponseBody    //等于response.setContentType("application/json;charset=utf-8");
    public User info() {
        return new User().setAccount("lisi").setGender("男").setAge(18)
                .setPassword("123").setBirthday(new Date());
    }

但是返回的Date数据是时间戳,需要在spring mvc配置文件中设置格式

2.3.3 SpringMVC配置文件

方式三中配置:

  <!-- 2.handleradapter:处理器适配器,用来调用handler的方法(处理请求) -->
  <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
         <property name="messageConverters">
             <list>
                 <ref bean="messageConverter"/>
             </list>
         </property>
  </bean>
  <!-- 消息转换器 -->
  <bean id="messageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
         <property name="objectMapper" ref="jackson"></property>
         <property name="supportedMediaTypes">
          <list>
              <!-- 针对不同类型的数据指定字符编码 -->
              <value>application/json;charset=UTF-8</value>
              <value>text/html;charset=UTF-8</value>
          </list>
      </property>
  </bean>
  <!-- jackson -->
  <bean id="jackson" class="com.fasterxml.jackson.databind.ObjectMapper">
         <property name="dateFormat">
             <bean class="java.text.SimpleDateFormat">
                 <constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
             </bean>
         </property>
  </bean>

方式四:

  <!-- 方式四 -->
  <mvc:annotation-driven>
         <mvc:message-converters>
             <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                 <property name="objectMapper">
                     <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                         <property name="dateFormat">
                             <bean class="java.text.SimpleDateFormat">
                                 <constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
                             </bean>
                         </property>
                     </bean>
                 </property>
             </bean>
         </mvc:message-converters>
  </mvc:annotation-driven>

三、SSM整合

3.1 mybatis-config.xml

内容都整合到spring-context.xml中了

<?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>

</configuration>

3.2 spring-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        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: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
                      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">

    <!-- 一、Spring和Mybatis基础整合 -->
    <!-- 1.导入数据库配置文件 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 2.配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- 3.创建工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 设置数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 加载mybatis配置文件:项目中就不用单独加载mybatis的配置文件了-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>

        <!-- 取别名 -->
        <property name="typeAliasesPackage" value="com.woniuxy.entity"></property>
        <!-- 分页插件 -->
        <property name="plugins" ref="pageInterceptor"></property>
    </bean>

    <!-- 分页插件 -->
    <bean id="pageInterceptor" class="com.github.pagehelper.PageInterceptor"></bean>

    <!-- 4.扫描mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 指定扫描哪个包 -->
        <property name="basePackage" value="com.woniuxy.mapper"></property>
        <!-- 关联工厂 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>

    <!-- 扫描service -->
    <context:component-scan base-package="com.woniuxy.service"></context:component-scan>    

    <!-- 配置事务管理器:负责管理事务 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 指定管理哪个数据库 -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 事务扫描 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

注意:在WEB项目下,引入db.properties和mybatis-config.xml文件时需要在路径前面加上classpath:

3.3 spring-context-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        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"
    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
                      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">

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 3.视图解析器:将逻辑视图转换成物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>

    <!-- 4.扫描controller所在的包 -->
    <context:component-scan base-package="com.woniuxy.controller"></context:component-scan>

    <!-- 静态资源放行:不要拦截 -->
    <mvc:default-servlet-handler/>
</beans>

3.4 Entity实体类

@Data  //自动添加setter、getter、toString
@AllArgsConstructor    //全参
@NoArgsConstructor    //无参
@Accessors(chain=true)    //开启链式表达
public class Goods {
    private int id;
    private String name;            //商品名
    private String goodsno;            //商品编号
    private String author;            //作者
    private String publisher;        //出版社
    private String pubtime;            //出版时间
    private int categoryid;            //分类id
    private String description;        //详情描述
    private String image;            //图片
    private int stock;                //库存
    private BigDecimal marketprice;    //市场价
    private BigDecimal salesprice;    //惊喜价,销售价
    private BigDecimal score;        //评分
    private int remarknums;            //评论数
    private Date uptime;            //上架时间
    private int salenums;            //销量
    private String newest;            //是否为新上架
    private String hot;                //是否为热门商品
    private String status;            //状态
}

3.5 Mapper接口与XML

mapper接口:

@Repository
public interface GoodsMapper {
    //all
    public List<Goods> findAll();
    //
    public Goods findById(int id);
    //通过id修改商品价格
    public int updatePrice(@Param("id")int id,@Param("salesprice")BigDecimal salesprice);
}

mapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.woniuxy.mapper.GoodsMapper">
    <select id="findAll" resultType="Goods">
        select * from mall_goods
    </select>

    <select id="findById" resultType="Goods" parameterType="int">
        select * from mall_goods where id = #{id}
    </select>

    <update id="updatePrice">
        update mall_goods set salesprice = #{salesprice} where id = #{id}
    </update>
</mapper>

3.6 Service接口与Service实现类

Service接口:

public interface GoodsService {
    //以id查询
    public Goods findById(int id);
    //分页查询
    public List<Goods> findGoodsByPage(int page,int size);
    //通过id修改商品价格
    public int updatePrice(int id,BigDecimal salesprice);
}

Service实现类:

@Data
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsMapper goodsMapper;
    // 日志service
    @Autowired
    private GoodsLogService goodsLogService;

    @Override
    public List<Goods> findGoodsByPage(int page, int size) {
        Page<Goods> pageHelper = PageHelper.startPage(page, size);
        List<Goods> goods = goodsMapper.findAll();
        return goods;
    }

    @Override
    public Goods findById(int id) {
        return goodsMapper.findById(id);
    }

    @Override
    @Transactional
    public int updatePrice(int id, BigDecimal salesprice) {
        goodsMapper.updatePrice(id, salesprice);
        // 记录日志
        goodsLogService.add(new GoodsLog().setMsg("修改了价格"));
        // 手动制造异常,配置事务管理后,出现异常自动回滚
//        System.out.println(1/0);
        return 0;
    }
}

3.7 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SSM</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

  <!-- 1.配置项目启动时初始化参数 -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <!-- 加载spring的配置文件 -->
      <param-value>classpath:spring-context.xml</param-value>
  </context-param>
  <!-- 2.添加spring的监听器 -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 3.加载spring mvc的配置文件 -->
  <servlet>
      <servlet-name>spring-mvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <!-- 给DispatcherServlet中的属性赋值 -->
          <param-name>contextConfigLocation</param-name>
          <!-- classpath:指代的就是项目部署之后的classes目录 -->
          <param-value>classpath:spring-context-mvc.xml</param-value>
      </init-param>
  </servlet>
  <servlet-mapping>
      <servlet-name>spring-mvc</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

3.8 controller

@Data
@Controller
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    //分页查询
    @RequestMapping("/page")
    @ResponseBody
    public List<Goods> findGoodsByPage(int page){
        return goodsService.findGoodsByPage(page, 5);
    }

    @RequestMapping("/update")
    @ResponseBody
    public void update(int id,BigDecimal salesprice) {
        goodsService.updatePrice(id, salesprice);
    }
}