除了添加必要的dependencies外,其他需要设置的文件包括:
1. web.xml,加载dubbox dispatch servlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml, /WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</context-param>
<listener>
<listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
2. servlet-context.xml, 加载dubbo application配置,注意前面的配置作用是设置编码为utf-8,并忽略json中不存在的字段:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven>
<message-converters register-defaults="false">
<beans:bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:constructor-arg index="0" value="utf-8"/>
</beans:bean>
<beans:bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="objectMapper">
<beans:bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<beans:property name="featuresToDisable">
<util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES" />
</beans:property>
</beans:bean>
</beans:property>
</beans:bean>
</message-converters>
</annotation-driven>
<beans:bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"></beans:bean>
<dubbo:application name="dubbox-demo"/>
<dubbo:registry address="multicast://224.5.6.7:1234"/>
<dubbo:protocol name="rest" port="8080" server="servlet" contextpath="dubbox"></dubbo:protocol>
<beans:bean id="helloService" class="com.abel.dubbox.impl.HelloServiceImpl"></beans:bean>
<dubbo:service interface="com.abel.dubbox.HelloService" ref="helloService"></dubbo:service>
<beans:bean id="userService" class="com.abel.dubbox.impl.UserServiceImpl"></beans:bean>
<dubbo:service interface="com.abel.dubbox.UserService" ref="userService"></dubbo:service>
</beans:beans>
3. 注意为了正确解析日期时间类型,本示例采用了ISO格式传递,主要引用了两个序列化/反系列化两个类:
package com.smart.sso.server.model;
import java.util.Date;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.abel.bigwater.model.JsonDateDeserializer;
import com.abel.bigwater.model.JsonDateSerializer;
import com.alibaba.fastjson.annotation.JSONField;
import com.smart.mvc.enums.TrueFalseEnum;
import com.smart.mvc.model.PersistentObject;
/**
* 管理员
*
* @author Joe
*/
public class User extends PersistentObject {
private static final long serialVersionUID = 1106412532325860697L;
/** 登录名 */
private String account;
/** 密码 */
private String password;
/** 最后登录IP */
private String lastLoginIp;
/** 登录总次数 */
private Integer loginCount = Integer.valueOf(0);
/** 最后登录时间 */
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date lastLoginTime;
/** 创建时间 */
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 是否启用 */
private Boolean isEnable = Boolean.valueOf(true);
/** 部门编号 */
private Integer deptId;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getLastLoginIp() {
return lastLoginIp;
}
public void setLastLoginIp(String lastLoginIp) {
this.lastLoginIp = lastLoginIp;
}
public Integer getLoginCount() {
return loginCount;
}
public void setLoginCount(Integer loginCount) {
this.loginCount = loginCount;
}
@JsonSerialize(using = JsonDateSerializer.class)
public Date getLastLoginTime() {
return lastLoginTime;
}
@JsonDeserialize(using = JsonDateDeserializer.class)
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
@JsonSerialize(using = JsonDateSerializer.class)
public Date getCreateTime() {
return createTime;
}
@JsonDeserialize(using = JsonDateDeserializer.class)
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Boolean getIsEnable() {
return isEnable;
}
public void setIsEnable(Boolean isEnable) {
this.isEnable = isEnable;
}
public String getIsEnableStr() {
return (isEnable != null && isEnable) ? TrueFalseEnum.TRUE.getLabel() : TrueFalseEnum.FALSE.getLabel();
}
/**
* @return the deptId
*/
public Integer getDeptId() {
return deptId;
}
/**
* @param deptId the deptId to set
*/
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
}
其中 JsonDateSerializer类:
package com.abel.bigwater.model;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
public class JsonDateSerializer extends JsonSerializer<Date> {
private SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSSZ");
@Override
public void serialize(Date date, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
String value = dateFormat.format(date);
jgen.writeString(value);
}
}
JsonDateDeserializer类:
package com.abel.bigwater.model;
import java.io.IOException;
import java.util.Date;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
public class JsonDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return JsonHelperJava.parseISODate(jp.getText());
}
}
JsonHelperJava类:
package com.abel.bigwater.model;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public final class JsonHelperJava {
private JsonHelperJava() {
// nothing
}
public static final String FULL_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSX";
public static final String FULL_DATE_FORMAT_NO_AREA = "yyyy-MM-dd'T'HH:mm:ss.SSS";
public static final String FULL_DATE_FORMAT_NO_MILLI = "yyyy-MM-dd'T'HH:mm:ssX";
public static final String FULL_ISODATE_FORMAT_NO_MILLI = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static final String FULL_DATE_FORMAT_NO_MILLI_AREA = "yyyy-MM-dd'T'HH:mm:ss";
public static final String DATE_MIN_FORMAT = "yyyy-MM-dd'T'HH:mmX";
public static final String DATE_MIN_FORMAT_NO_AREA = "yyyy-MM-dd'T'HH:mm";
/**
* parses string with iso-date-format/other precise date-format/default date-format.
*
* @param str
* @param dv
* @return
*/
public static Date parseISODate(String str) {
if (str == null) {
return null;
}
// str = str.replace('T', ' ');
SimpleDateFormat sdf = new SimpleDateFormat(FULL_DATE_FORMAT);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
sdf = new SimpleDateFormat(FULL_ISODATE_FORMAT_NO_MILLI);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
// if invalid 1.
sdf = new SimpleDateFormat(FULL_DATE_FORMAT_NO_AREA);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
// if invalid 2.
sdf = new SimpleDateFormat(FULL_DATE_FORMAT_NO_MILLI);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
// if no area & no millis.
sdf = new SimpleDateFormat(FULL_DATE_FORMAT_NO_MILLI_AREA);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
// if no seconds
sdf = new SimpleDateFormat(DATE_MIN_FORMAT);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
// if no seconds & area
sdf = new SimpleDateFormat(DATE_MIN_FORMAT_NO_AREA);
try {
return sdf.parse(str);
} catch (Exception ex) {
// nothing.
}
try {
return DateFormat.getInstance().parse(str);
} catch (Exception ex) {
// does nothing
}
return null;
}
}