(该示例是使用eclipse搭建的一个maven项目,如何搭建可以看我的前一篇博文,这样可以保证版本Webapp版本以及jdk版本一致。project的文件结构如下图所示)
接下来,我们就开始一步步的完成这个简单的实例,相信会帮助那些不了解springMVC的同学对其有个初步的认识
0.最开始我们要配pom.xml,把依赖的包都配进去
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>cutsubmit</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>cutsubmit Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<springframework>4.3.6.RELEASE</springframework>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>0.10.2.0</version>
</dependency>
</dependencies>
<build>
<finalName>cutsubmit</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.好的,正式开始,首先我们需要修改webapp/WEB_INF下的web.xml文件,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:kafka-beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc-dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
当服务器启动时,服务器会读取web.xml配置,当读到<listener></listener>和<context-param></context-param>的时候,容器会将其中的信息放到ServletContext(上下文对象)中,这样我们在程序中就能通过这个上下文对象去取得我们这个配置值,我们在其中先把一会将要写的kafka-beans.xml配进去。然后我们把将要写的spring-mvc-dispatcher.xml配到servlet中。
2.接下来我们编写spring-mvc-dispatcher.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: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-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.test.controller"></context:component-scan>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
在context:component-scan节点中把我们自己的com.test.controller配进去,该base-package属性会告诉spring要扫描的包。
在bean节点中的配置可以让spring把url映射到/WEB-INF/views下以jsp为结尾的文件,例如访问localhost:8080/cutsubmit/getmessage就对应了views下的getmessage.jsp文件。
3.编写kafka-beans.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: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-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.test.producer"></context:component-scan>
<bean id="kafkaProducerDemo" class="com.test.producer.KafkaProducerDemo">
<property name="properties">
<props>
<prop key="topic">tile_job6</prop>
<prop key="bootstrap.servers">192.168.44.147:9092</prop>
<prop key="acks">all</prop>
<prop key="key.serializer">org.apache.kafka.common.serialization.StringSerializer
</prop>
<prop key="value.serializer">org.apache.kafka.common.serialization.StringSerializer
</prop>
<prop key="buffer.memory">33554432</prop>
</props>
</property>
</bean>
</beans>
把com.test.producer配到base-package中。然后将KafkaProducerDemo注入,property name="properties"对应了KafkaProducerDemo类中的properties属性,然后properties中有topic,bootstrap.servers,arks等kafka相关配置。
4.编写MyController.java类
package com.test.controller;
import java.awt.Dialog.ModalExclusionType;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.annotation.JsonViewRequestBodyAdvice;
import com.alibaba.fastjson.JSONObject;
import com.test.producer.KafkaProducerDemo;
@Controller
public class MyController {
@Resource(name="kafkaProducerDemo")
KafkaProducerDemo producer;
@RequestMapping(value = "/getmessage", method = RequestMethod.POST)
public String getMessage(HttpServletRequest request, Model model) {
String teString = "{\"type\":1,\"param\":\"{\\\"id\\\":0,\\\"taskid\\\":\\\"tif-6799102970cb41d7a9bc25d8cd599a90\\\",\\\"num\\\":1,\\\"taskthreadnum\\\":33,\\\"isBase\\\":0,\\\"iswal\\\":0,\\\"isPhase\\\":0,\\\"isMerge\\\":0,\\\"layername\\\":\\\"tif-6799102970cb41d7a9bc25d8cd599a90\\\",\\\"sourcepath\\\":\\\"/home/ssy/8760\\\",\\\"bbox\\\":null,\\\"select_importtype\\\":\\\"images\\\",\\\"idxstart\\\":0,\\\"idxstop\\\":0,\\\"postfix\\\":\\\".tiff\\\",\\\"layertype\\\":0,\\\"defaultidx\\\":null,\\\"isbasechecked\\\":null,\\\"isphasechecked\\\":null,\\\"iswalchecked\\\":null,\\\"pixcutter\\\":0,\\\"timestamp\\\":null,\\\"outformat\\\":0,\\\"imageMetaId\\\":8760}\"}";
JSONObject jsonObject = JSONObject.parseObject(teString);
String sourcepath = request.getParameter("sourcepath");
String outformat = request.getParameter("outformat");
System.out.println(outformat);
String timeString = System.currentTimeMillis()+"";
String uuidString = UUID.randomUUID().toString();
String taskidAndLayername = timeString + uuidString.substring(uuidString.length()-20);
JSONObject paramObject = JSONObject.parseObject(jsonObject.getString("param"));
paramObject.put("taskid", taskidAndLayername);
paramObject.put("layername", taskidAndLayername);
paramObject.put("outformat", Integer.parseInt(outformat));
paramObject.put("sourcepath", sourcepath);
jsonObject.put("param", paramObject);
String newJsonString = jsonObject.toString();
System.out.println(newJsonString);
String topic = producer.getProperties().getProperty("topic");
model.addAttribute("message", newJsonString);
model.addAttribute("topic", topic);
if(producer.sendMessage(newJsonString)) {
return "getmessage";
}else {
return "false";
}
}
}
首先是将一个字符串转成JSON对象,然后用表单中传入的sourcepath和outformat值替换JSON中对应的值,以及用一个带时间戳的不重复变量代替JSON对象中的layername和taskid的值(我也不知道我为啥写了这么一段,可能当时抽风了想看看阿里的fastjson咋用的)。然后把该JSON对象转回字符串,用kafka发出去。成功就跳到getmessage.jsp,失败就跳到false.jsp。
5.编写KafkaProducerDemo.java类,代码如下:
package com.test.producer;
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
public class KafkaProducerDemo {
private Properties properties;
public KafkaProducerDemo(Properties properties) {
this.properties = properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Properties getProperties() {
return properties;
}
public boolean sendMessage(String message) {
try {
KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
ProducerRecord<String, String> record = new ProducerRecord<String, String>(properties.getProperty("topic"), message);
producer.send(record);
producer.close();
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
很简单的一个类,简单的实现了kafka的producer发个消息。
6.表单index.jsp
<html>
<body>
<form action = "getmessage" method="post">
profile path:<input type="text" name="sourcepath"/><br/>
mime type(0:png,1:jpeg,2:tiff):<input type="text" name="outformat"/>
<input type="submit" value="submit" />
</form>
</body>
</html>
很简单很丑的一个表单,凑合用吧。。。
7.getmessage.jsp和false.jsp
getmessage.jsp如下
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
send message:${message} to ${topic} success }
</body>
</html>
false.jsp如下:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
kafka send message to ${topic} error}
</body>
</html>
OK,大功告成。看看啥效果吧:
然后我们在服务器上创建个consumer,可以接收到我们发的消息。
首先进入kafka/bin,然后输入命令创建consumer,此时终端上没有任何信息,
然后点击我们的表单的submit让消息发送出去,然后就可以看到终端接收到了我们发的消息。