(該示例是使用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讓消息發送出去,然後就可以看到終端接收到了我們發的消息。
(彳亍吧,我知道是個很簡陋的一個小例子,不過還是希望能對大家有些許幫助)