Active整合Spring

1 课程计划

第八天:

  1. Activemq整合springMQ的应用场景
  2. 添加商品同步索引库
  3. 商品详情页面动态展示
  4. 展示详情页面使用缓存

2 Activemq整合spring

2.1 使用方法

第一步:引用相关的jar包。

<dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-jms</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-context-support</artifactId>

            </dependency>

第二步:配置Activemq整合spring。配置ConnectionFactory

在e3-manager-service创建applicationContext-activemq.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: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.2.xsd

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

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

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

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

 

 

      <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

      <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

            <property name="brokerURL" value="tcp://192.168.25.168:61616" />

      </bean>

      <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

      <bean id="connectionFactory"

            class="org.springframework.jms.connection.SingleConnectionFactory">

            <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

            <property name="targetConnectionFactory" ref="targetConnectionFactory" />

      </bean>

</beans>

第三步:配置生产者。

使用JMSTemplate对象。发送消息。

第四步:在spring容器中配置Destination。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="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.2.xsd

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

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

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

 

      <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

      <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

            <property name="brokerURL" value="tcp://192.168.25.167:61616" />

      </bean>

      <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

      <bean id="connectionFactory"

            class="org.springframework.jms.connection.SingleConnectionFactory">

            <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

            <property name="targetConnectionFactory" ref="targetConnectionFactory" />

      </bean>

      <!-- 配置生产者 -->

      <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->

      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

            <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->

            <property name="connectionFactory" ref="connectionFactory" />

      </bean>

      <!--这个是队列目的地,点对点的 -->

      <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">

            <constructor-arg>

                  <value>spring-queue</value>

            </constructor-arg>

      </bean>

      <!--这个是主题目的地,一对多的 -->

      <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">

            <constructor-arg value="topic" />

      </bean>

</beans>

第五步:代码测试

在e3-manager-service工程创建测试类:

@Test

      public void testSpringActiveMq() throws Exception {

            //初始化spring容器

            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-activemq.xml");

            //从spring容器中获得JmsTemplate对象

            JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);

            //从spring容器中取Destination对象

            Destination destination = (Destination) applicationContext.getBean("queueDestination");

            //使用JmsTemplate对象发送消息。

            jmsTemplate.send(destination, new MessageCreator() {

                 

                  @Override

                  public Message createMessage(Session session) throws JMSException {

                        //创建一个消息对象并返回

                        TextMessage textMessage = session.createTextMessage("spring activemq queue message");

                        return textMessage;

                  }

            });

      }

启动消费者:

2.2 代码测试

2.2.1 发送消息

第一步:初始化一个spring容器

第二步:从容器中获得JMSTemplate对象。

第三步:从容器中获得一个Destination对象

第四步:使用JMSTemplate对象发送消息,需要知道Destination

@Test

      public void testQueueProducer() throws Exception {

            // 第一步:初始化一个spring容器

            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-activemq.xml");

            // 第二步:从容器中获得JMSTemplate对象。

            JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);

            // 第三步:从容器中获得一个Destination对象

            Queue queue = (Queue) applicationContext.getBean("queueDestination");

            // 第四步:使用JMSTemplate对象发送消息,需要知道Destination

            jmsTemplate.send(queue, new MessageCreator() {

                 

                  @Override

                  public Message createMessage(Session session) throws JMSException {

                        TextMessage textMessage = session.createTextMessage("spring activemq test");

                        return textMessage;

                  }

            });

      }

2.2.2 接收消息

e3-search-Service中接收消息复制applicationContext-activemq.xml配置文件到工程下。

第一步:把Activemq相关的jar包添加到工程中

第二步:创建一个MessageListener的实现类。

public class MyMessageListener implements MessageListener {

 

      @Override

      public void onMessage(Message message) {

           

            try {

                  TextMessage textMessage = (TextMessage) message;

                  //取消息内容

                  String text = textMessage.getText();

                  System.out.println(text);

            } catch (JMSException e) {

                  e.printStackTrace();

            }

      }

 

}

第三步:配置spring和Activemq整合。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="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.2.xsd

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

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

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

 

      <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

      <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

            <property name="brokerURL" value="tcp://192.168.25.167:61616" />

      </bean>

      <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

      <bean id="connectionFactory"

            class="org.springframework.jms.connection.SingleConnectionFactory">

            <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

            <property name="targetConnectionFactory" ref="targetConnectionFactory" />

      </bean>

      <!--这个是队列目的地,点对点的 -->

      <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">

            <constructor-arg>

                  <value>spring-queue</value>

            </constructor-arg>

      </bean>

      <!--这个是主题目的地,一对多的 -->

      <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">

            <constructor-arg value="topic" />

      </bean>

      <!-- 接收消息 -->

      <!-- 配置监听器 -->

      <bean id="myMessageListener" class="cn.e3mall.search.listener.MyMessageListener" />

      <!-- 消息监听容器 -->

      <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">

            <property name="connectionFactory" ref="connectionFactory" />

            <property name="destination" ref="queueDestination" />

            <property name="messageListener" ref="myMessageListener" />

      </bean>

</beans>

第四步:测试代码。

@Test

      public void testQueueConsumer() throws Exception {

            //初始化spring容器

            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-activemq.xml");

            //等待

            System.in.read();

      }

3 添加商品同步索引库

e3-search-service(消费者):

ItemMapper.java:

ItemMapper.xml:

ItemAddMessageListener.java:

applicationContext-activemq.xml配置消费者生效 (被多个客户端接受使用topic):

e3-manager-service(消息提供者):

applicationContext-activemq.xml:

ItemServiceImpl:

在添加商品的方法中(问题:事务还没提交那边已经查数据库可能导致空指针异常):

解决空指针异常(接受消息时等待1秒或者在事务提交后在controller层进行消息发送):

e3-search-service:

ItemAddMessageListener.java:

切换solr为单机版测试:

e3-search-service:

applicationContext-solr.xml:

启动zookeeper单机版 redis单机版 solr单机版即可

/3.1 Producer()

e3-manager-server工程中发送消息。

当商品添加完成后发送一个TextMessage,包含一个商品id。

@Override

      public e3Result addItem(TbItem item, String desc) {

            // 1、生成商品id

            final long itemId = IDUtils.genItemId();

            // 2、补全TbItem对象的属性

            item.setId(itemId);

            //商品状态,1-正常,2-下架,3-删除

            item.setStatus((byte) 1);

            Date date = new Date();

            item.setCreated(date);

            item.setUpdated(date);

            // 3、向商品表插入数据

            itemMapper.insert(item);

            // 4、创建一个TbItemDesc对象

            TbItemDesc itemDesc = new TbItemDesc();

            // 5、补全TbItemDesc的属性

            itemDesc.setItemId(itemId);

            itemDesc.setItemDesc(desc);

            itemDesc.setCreated(date);

            itemDesc.setUpdated(date);

            // 6、向商品描述表插入数据

            itemDescMapper.insert(itemDesc);

            //发送一个商品添加消息

            jmsTemplate.send(topicDestination, new MessageCreator() {

                 

                  @Override

                  public Message createMessage(Session session) throws JMSException {

                        TextMessage textMessage = session.createTextMessage(itemId + "");

                        return textMessage;

                  }

            });

            // 7e3Result.ok()

            return e3Result.ok();

      }

3.2 Consumer()

3.2.1 功能分析

  1. 接收消息。需要创建MessageListener接口的实现类。
  2. 取消息,取商品id。
  3. 根据商品id查询数据库。
  4. 创建一SolrInputDocument对象。
  5. 使用SolrServer对象写入索引库。
  6. 返回成功,返回e3Result。

3.2.2 Dao层

根据商品id查询商品信息。

映射文件:

<select id="getItemById" parameterType="long" resultType="cn.e3mall.common.pojo.SearchItem">

            SELECT

                  a.id,

                  a.title,

                  a.sell_point,

                  a.price,

                  a.image,

                  b. NAME category_name,

                  c.item_desc

            FROM

                  tb_item a

            JOIN tb_item_cat b ON a.cid = b.id

            JOIN tb_item_desc c ON a.id = c.item_id

            WHERE a.status = 1

              AND a.id=#{itemId}

      </select>

3.2.3 Service层

参数:商品ID

业务逻辑:

  1. 根据商品id查询商品信息。
  2. 创建一SolrInputDocument对象。
  3. 使用SolrServer对象写入索引库。
  4. 返回成功,返回e3Result。

返回值:e3Result

public e3Result addDocument(long itemId) throws Exception {

            // 1、根据商品id查询商品信息。

            SearchItem searchItem = searchItemMapper.getItemById(itemId);

            // 2、创建一SolrInputDocument对象。

            SolrInputDocument document = new SolrInputDocument();

            // 3、使用SolrServer对象写入索引库。

            document.addField("id", searchItem.getId());

            document.addField("item_title", searchItem.getTitle());

            document.addField("item_sell_point", searchItem.getSell_point());

            document.addField("item_price", searchItem.getPrice());

            document.addField("item_image", searchItem.getImage());

            document.addField("item_category_name", searchItem.getCategory_name());

            document.addField("item_desc", searchItem.getItem_desc());

            // 5、向索引库中添加文档。

            solrServer.add(document);

            solrServer.commit();

            // 4、返回成功,返回e3Result

            return e3Result.ok();

      }

3.2.4 Listener

public class ItemChangeListener implements MessageListener {

     

      @Autowired

      private SearchItemServiceImpl searchItemServiceImpl;

 

      @Override

      public void onMessage(Message message) {

            try {

                  TextMessage textMessage = null;

                  Long itemId = null;

                  //取商品id

                  if (message instanceof TextMessage) {

                        textMessage = (TextMessage) message;

                        itemId = Long.parseLong(textMessage.getText());

                  }

                  //向索引库添加文档

                  searchItemServiceImpl.addDocument(itemId);

                 

            } catch (Exception e) {

                  e.printStackTrace();

            }

      }

 

}

3.2.5 Spring配置监听

/

3.2.6 实现流程

4 商品详情页面展示

创建一个商品详情页面展示的工程。是一个表现层工程。

4.1 工程搭建

e3-item-web。打包方式war。可以参考e3-portal-web

4.1.1 Pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <parent>

            <groupId>cn.e3mall</groupId>

            <artifactId>e3-parent</artifactId>

            <version>0.0.1-SNAPSHOT</version>

      </parent>

      <groupId>cn.e3mall</groupId>

      <artifactId>e3-item-web</artifactId>

      <version>0.0.1-SNAPSHOT</version>

      <packaging>war</packaging>

      <dependencies>

            <dependency>

                  <groupId>cn.e3mall</groupId>

                  <artifactId>e3-manager-interface</artifactId>

                  <version>0.0.1-SNAPSHOT</version>

            </dependency>

            <!-- Spring -->

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-context</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-beans</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-webmvc</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-jdbc</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-aspects</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-jms</artifactId>

            </dependency>

            <dependency>

                  <groupId>org.springframework</groupId>

                  <artifactId>spring-context-support</artifactId>

            </dependency>

            <!-- JSP相关 -->

            <dependency>

                  <groupId>jstl</groupId>

                  <artifactId>jstl</artifactId>

            </dependency>

            <dependency>

                  <groupId>javax.servlet</groupId>

                  <artifactId>servlet-api</artifactId>

                  <scope>provided</scope>

            </dependency>

            <dependency>

                  <groupId>javax.servlet</groupId>

                  <artifactId>jsp-api</artifactId>

                  <scope>provided</scope>

            </dependency>

            <!-- dubbo相关 -->

            <dependency>

                  <groupId>com.alibaba</groupId>

                  <artifactId>dubbo</artifactId>

                  <!-- 排除依赖 -->

                  <exclusions>

                        <exclusion>

                              <groupId>org.springframework</groupId>

                              <artifactId>spring</artifactId>

                        </exclusion>

                        <exclusion>

                              <groupId>org.jboss.netty</groupId>

                              <artifactId>netty</artifactId>

                        </exclusion>

                  </exclusions>

            </dependency>

            <dependency>

                  <groupId>org.apache.zookeeper</groupId>

                  <artifactId>zookeeper</artifactId>

            </dependency>

            <dependency>

                  <groupId>com.github.sgroschupf</groupId>

                  <artifactId>zkclient</artifactId>

            </dependency>

            <dependency>

                  <groupId>junit</groupId>

                  <artifactId>junit</artifactId>

            </dependency>

      </dependencies>

      <!-- 配置tomcat插件 -->

      <build>

            <plugins>

                  <plugin>

                        <groupId>org.apache.tomcat.maven</groupId>

                        <artifactId>tomcat7-maven-plugin</artifactId>

                        <configuration>

                              <port>8086</port>

                              <path>/</path>

                        </configuration>

                  </plugin>

            </plugins>

      </build>

</project>

复制配置文件:

1.删除resource.properties内容

2.修改springmvc.xml配置文件:

创建包:

复制web.xml配置文件:

复制静态资源:

4.2 功能分析

在搜索结果页面点击商品图片或者商品标题,展示商品详情页面。

请求的url:/item/{itemId}

参数:商品id

返回值:String 逻辑视图

业务逻辑:

1. 从url中取参数,商品id

2. 根据商品id查询商品信息(tb_item)得到一个TbItem对象,缺少images属性,可以创建一个pojo继承TbItem,添加一个getImages方法。在e3-item-web工程中。

public class Item extends TbItem {

 

      public String[] getImages() {

            String image2 = this.getImage();

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

                  String[] strings = image2.split(",");

                  return strings;

            }

            return null;

      }

     

      public Item() {

           

      }

     

      public Item(TbItem tbItem) {

            this.setBarcode(tbItem.getBarcode());

            this.setCid(tbItem.getCid());

            this.setCreated(tbItem.getCreated());

            this.setId(tbItem.getId());

            this.setImage(tbItem.getImage());

            this.setNum(tbItem.getNum());

            this.setPrice(tbItem.getPrice());

            this.setSellPoint(tbItem.getSellPoint());

            this.setStatus(tbItem.getStatus());

            this.setTitle(tbItem.getTitle());

            this.setUpdated(tbItem.getUpdated());

      }

     

}

3. 根据商品id查询商品描述。

4. 展示到页面。

4.3 Dao层

查询tb_item, tb_item_desc两个表,都是单表查询。可以使用逆向工程。

4.4 Service层

  1. 根据商品id查询商品信息

参数:商品id

返回值:TbItem

  1. 根据商品id查询商品描述

参数:商品id

返回值:TbItemDesc

@Override

      public TbItemDesc getItemDescById(long itemId) {

            TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId);

            return itemDesc;

      }

 

 

4.5 表现层

4.5.1 Controller

请求的url:/item/{itemId}

参数:商品id

返回值:String 逻辑视图

@Controller

public class ItemController {

 

      @Autowired

      private ItemService itemService;

     

      @RequestMapping("/item/{itemId}")

      public String showItemInfo(@PathVariable Long itemId, Model model) {

            //跟据商品id查询商品信息

            TbItem tbItem = itemService.getItemById(itemId);

            //把TbItem转换成Item对象

            Item item = new Item(tbItem);

            //根据商品id查询商品描述

            TbItemDesc tbItemDesc = itemService.getItemDescById(itemId);

            //把数据传递给页面

            model.addAttribute("item", item);

            model.addAttribute("itemDesc", tbItemDesc);

            return "item";

      }

}

引用服务

4.6 向业务逻辑中添加缓存

4.6.1 缓存添加分析

使用redis做缓存。

复制applicationContext-redis.xml配置文件到e3-manager-service工程:

 

业务逻辑:

  1. 根据商品id到缓存中命中
  2. 查到缓存,直接返回。
  3. 差不到,查询数据库
  4. 把数据放到缓存中
  5. 返回数据

 

缓存中缓存热点数据,提供缓存的使用率。需要设置缓存的有效期。一般是一天的时间,可以根据实际情况跳转。

 

需要使用String类型来保存商品数据。

可以加前缀方法对象redis中的key进行归类。

ITEM_INFO:123456:BASE

ITEM_INFO:123456:DESC

如果把二维表保存到redis中:

  1. 表名就是第一层
  2. 主键是第二层
  3. 字段名第三次

三层使用“:”分隔作为key,value就是字段中的内容。

4.6.2 把redis相关的jar包添加到工程

4.6.3 添加缓存

配置resource.properties:

applicationContext-dao.xml配置文件修改加载配置文件:

引入缓存对象:

@Override

      public TbItem getItemById(long itemId) {

            try {

                  //查询缓存

                  String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":BASE");

                  if (StringUtils.isNotBlank(json)) {

                        //json转换为java对象

                        TbItem item = JsonUtils.jsonToPojo(json, TbItem.class);

                        return item;

                  }

            } catch (Exception e) {

                  e.printStackTrace();

            }

            //根据商品id查询商品信息

            //TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);

            TbItemExample example = new TbItemExample();

            //设置查询条件

            Criteria criteria = example.createCriteria();

            criteria.andIdEqualTo(itemId);

            List<TbItem> list = itemMapper.selectByExample(example);

            if (list != null && list.size() > 0) {

                  TbItem item = list.get(0);

                  try {

                        //把数据保存到缓存

                        jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":BASE", JsonUtils.objectToJson(item));

                        //设置缓存的有效期

                        jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":BASE", ITEM_INFO_EXPIRE);

                  } catch (Exception e) {

                        e.printStackTrace();

                  }

                  return item;

            }

            return null;

      }

取商品描述添加缓存:

@Override

      public TbItemDesc getItemDescById(long itemId) {

            try {

                  String json = jedisClient.get(ITEM_INFO_PRE + ":" + itemId + ":DESC");

                  //判断缓存是否命中

                  if (StringUtils.isNotBlank(json) ) {

                        //转换为java对象

                        TbItemDesc itemDesc = JsonUtils.jsonToPojo(json, TbItemDesc.class);

                        return itemDesc;

                  }

            } catch (Exception e) {

                  e.printStackTrace();

            }

            TbItemDesc itemDesc = itemDescMapper.selectByPrimaryKey(itemId);

            try {

                  jedisClient.set(ITEM_INFO_PRE + ":" + itemId + ":DESC", JsonUtils.objectToJson(itemDesc));

                  //设置过期时间

                  jedisClient.expire(ITEM_INFO_PRE + ":" + itemId + ":DESC", ITEM_INFO_EXPIRE);

            } catch (Exception e) {

                  e.printStackTrace();

            }

            return itemDesc;

      }

 

5 FreeMarker测试类

安装freemarker插件:

复制到ecplise下的dropins目录下:

创建模板文件:

添加jar包:

在表现层e3-item-web创建测试类:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值