使用jaxb注解的小技巧-给xml结构增加封装

1.使用maven引入jaxb依赖

jdk1.6以上自带了jaxb,但我还是推荐显式指定依赖:

<dependency>
  <groupid>javax.xml.bind</groupid>
  <artifactid>jaxb-api</artifactid>
  <version>2.2.7</version>
</dependency>

2.构造一个封装类

下面的类Wrapper,使用Wrapper.wrapper(yourObject),就能把yourObject的结构封装在<root><yourObject></yourObject></root>标签里。

@XmlRootElement(name = "root")
public class Wrapper {

	public static Wrapper wrapper(Object object) {
		Wrapper wrapper = new Wrapper();
		wrapper.addElement(object);
		return wrapper;
	}

	@XmlAnyElement
	private List<Object> root;

	private Wrapper() {
		root = new ArrayList<Object>();
	}

	public void addElement(Object object) {
		root.add(object);
	}
}

如果需要修改外层的封装标签,修改@XmlRootElement(name = “your_tag”)即可。

如何配置spring web-mvc返回资源的xml/json等不同视图

1.首先,列出两个很有用的资源:

  1. Spring 3 MVC ContentNegotiatingViewResolver Example

  2. Spring REST 3 to Support XML and JSON

我按照链接1说明下载了示例代码,根据链接2解决了示例代码中的问题。

2.spring web-mvc是怎样区分不同的视图请求(xml or json or ?)

spring web-mvc支持给资源返回不同形式的视图,现在有两种方式指定返回的视图类型:

a.通过URL后缀指定视图类型

  • http://sample.com/resource.xml 返回资源的xml视图
  • http://sample.com/resource.json 返回资源的json视图

b.通过在HTTP请求头的Accept参数里列出期望的资源类型(media-types)

  • Accept:application/xml 指定返回xml视图
  • Accept:application/json 指定返回json视图

3.配置ContentNegotiatingViewResolver来支持返回多种视图

下面是配置ContentNegotiatingViewResolver的一段spring配置文件:

<bean
  class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"
  p:order="1">
  <property name="mediaTypes">
    <map>
      <entry key="xml" value="application/xml" />
      <entry key="json" value="application/json" />
    </map>
  </property>
  <property name="defaultViews">
    <list>
      <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
        <property name="marshaller">
          <bean class="org.springframework.oxm.xstream.XStreamMarshaller"
            p:autodetectAnnotations="true" />
        </property>
      </bean>
      <bean
        class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
    </list>
  </property>
</bean>

这段配置需要说明的有:

  1. 指定”后缀-资源类型”映射:<entry key=”xml” value=”application/xml” />,这样通过后缀就能对应到资源类型。
  2. 提供处理xml/json资源类型的bean,这里用来处理xml视图的bean是org.springframework.web.servlet.view.xml.MarshallingView,处理json视图的bean是
    org.springframework.web.servlet.view.json.MappingJacksonJsonView。

4.实现一个简单的Controller

class Somebody {
  private String name;
  private boolean isMale;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public boolean isMale() {
    return isMale;
  }

  public void setMale(boolean isMale) {
    this.isMale = isMale;
  }
}

@Controller
@RequestMapping("/hi")
public class Hi {
  @RequestMapping(value = "{name}", method = RequestMethod.GET)
  public @ModelAttribute
  Somebody getShopInJSON(@PathVariable String name) {
    Somebody somebody = new Somebody();
    somebody.setName(name);
    somebody.setMale(true);
    return somebody;
  }
}

注意!这里返回的对象,用的是@ModelAttribute注解。

5.部署和测试

把工程打成war包,部署到web容器下测试,访问http://host:port/hi/bob.json或是http://host:port/hi/bob.xml。

列下我的pom.xml的依赖:

...
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>

    <!-- for xml -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.thoughtworks.xstream</groupId>
      <artifactId>xstream</artifactId>
      <version>1.4.3</version>
    </dependency>

    <!-- for json -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.10</version>
    </dependency>

  </dependencies>
</project>

最后,感谢…!

使用maven WSDL2Code插件生成webservice代码

首先,配置我们的项目使用wsdl2code插件。

先看看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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sample</groupId>
  <artifactId>wesd2code-demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-wsdl2code-maven-plugin</artifactId>
        <version>1.6.2</version>
        <configuration>
          <packageName>com.sample</packageName>
          <wsdlFile>src/main/wsdl/webservice.wsdl</wsdlFile>
          <generateTestcase>true</generateTestcase>
          <syncMode>sync</syncMode>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

这里给大家解释下上面的wsdl2code插件配置

  1. packageName:生成的源码会放到指定的package里
  2. wsdlFile:webservice定义文件的路径,可以是相对于pom.xml所在目录的相对路径
  3. generateTestcase:是否生成单元测试
  4. syncMode:生成同步还是异步接口,有三种可选值:sync, async或者both,其中both是默认选项
  5. generateServerSide:默认是false,这里没有配置,所以是只生成客户端代码
  6. outputDirectory:默认是target/generated-sources/axis2/wsdl2code

然后,我们可以运行mvn命令生成代码:

mvn clean axis2-wsdl2code:wsdl2code

最后,给生成的代码添加依赖:

  <dependencies>
    <dependency>
      <groupId>org.apache.axis2</groupId>
      <artifactId>axis2-integration</artifactId>
      <version>1.6.2</version>
    </dependency>
  </dependencies>

Maven使用体会及一些最佳实践

maven官网的介绍太简略(Run Maven),对于一些初次接触maven的用户来说,实在是让人困惑。
本文主要介绍了maven的一些常见用法,大家籍着了解一些maven的功能。

1.使用maven标准的目录结构来组织项目

maven引入了convention over configuration(约定优先配置)的原则,如果你的项目是按照maven标准的目录结构来组织,很多时候都不用写自己的配置。

2.明确指定字符编码

特别是对于需要使用非ASCII字符的开发者来说,字符编码是很严肃的一件事。
建议在你的pom.xml里添加下面的配置:

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

另外,单元测试时如果不明确指定字符编码,有可能输出乱码,甚至导致测试失败,建议配置:

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.7.1</version>
  <configuration>
    <argLine>-Dfile.encoding=UTF-8</argLine>
  </configuration>
</plugin>

具体解释请参考maven-surefire-plugin乱码问题

待续…