SpringRest自动生成WADL描述文件

主要用于wadl2java自动生成客户端代码,以及soapui导入测试rest接口
net.java.dev.wadl这个包比较难找,wadl-xmlbeans

package com.wamdy.web.rest.wadl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;

import org.apache.xmlbeans.XmlOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import net.java.dev.wadl.x2009.x02.ApplicationDocument;
import net.java.dev.wadl.x2009.x02.ApplicationDocument.Application;
import net.java.dev.wadl.x2009.x02.DocDocument.Doc;
import net.java.dev.wadl.x2009.x02.ParamDocument.Param;
import net.java.dev.wadl.x2009.x02.ParamStyle;
import net.java.dev.wadl.x2009.x02.RepresentationDocument.Representation;
import net.java.dev.wadl.x2009.x02.RequestDocument.Request;
import net.java.dev.wadl.x2009.x02.ResourceDocument.Resource;
import net.java.dev.wadl.x2009.x02.ResourcesDocument.Resources;
import net.java.dev.wadl.x2009.x02.ResponseDocument.Response;

@RestController
@RequestMapping("rest.wadl")
public class WADLController {
	String xs_namespace = "http://www.w3.org/2001/XMLSchema";
	@Autowired
	private RequestMappingHandlerMapping handlerMapping;
	@Autowired
	private WebApplicationContext webApplicationContext;

	@RequestMapping(method = RequestMethod.GET, produces = { "application/xml" })
	public @ResponseBody String generateWadl(HttpServletRequest request) {
		XmlOptions xmlOptions = new XmlOptions();
		xmlOptions.setCharacterEncoding("UTF-8");
		xmlOptions.setSaveAggressiveNamespaces();
		xmlOptions.setSavePrettyPrint();
		ApplicationDocument appdoc = ApplicationDocument.Factory.newInstance(xmlOptions);
		Application app = appdoc.addNewApplication();
		Doc doc = app.addNewDoc();
		doc.setTitle("Spring REST Service WADL");
		Resources wadResources = app.addNewResources();
		wadResources.setBase(getBaseUrl(request));

		Map<RequestMappingInfo, HandlerMethod> handletMethods = handlerMapping.getHandlerMethods();
		for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handletMethods.entrySet()) {
			HandlerMethod handlerMethod = entry.getValue();
			Object object = handlerMethod.getBean();
			Object bean = webApplicationContext.getBean(object.toString());
			boolean isRestContoller = bean.getClass().isAnnotationPresent(RestController.class);
			if (!isRestContoller) {
				continue;
			}
			RequestMappingInfo mappingInfo = entry.getKey();
			Set pattern = mappingInfo.getPatternsCondition().getPatterns();
			Set httpMethods = mappingInfo.getMethodsCondition().getMethods();
			ProducesRequestCondition producesRequestCondition = mappingInfo.getProducesCondition();
			Set mediaTypes = producesRequestCondition.getProducibleMediaTypes();
			Resource wadlResource = null;
			for (RequestMethod httpMethod : httpMethods) {
				for (String uri : pattern) {
					wadlResource = createOrFind(uri, wadResources);
					wadlResource.setPath(uri);
				}
				net.java.dev.wadl.x2009.x02.MethodDocument.Method wadlMethod = wadlResource.addNewMethod();
				wadlMethod.setName(httpMethod.name());
				Method javaMethod = handlerMethod.getMethod();
				wadlMethod.setId(javaMethod.getName());
				Doc wadlDocMethod = wadlMethod.addNewDoc();
				wadlDocMethod.setTitle(javaMethod.getDeclaringClass().getSimpleName() + "." + javaMethod.getName());

				// Request
				Request wadlRequest = wadlMethod.addNewRequest();

				Annotation[][] annotations = javaMethod.getParameterAnnotations();
				Class<?>[] paramTypes = javaMethod.getParameterTypes();
				int i = 0;
				for (Annotation[] annotation : annotations) {
					Class<?> paramType = paramTypes[i];
					i++;
					for (Annotation annotation2 : annotation) {

						if (annotation2 instanceof RequestParam) {
							RequestParam param2 = (RequestParam) annotation2;
							Param waldParam = wadlRequest.addNewParam();
							QName nm = convertJavaToXMLType(paramType);
							waldParam.setName(param2.value());
							waldParam.setStyle(ParamStyle.QUERY);
							waldParam.setRequired(param2.required());
							String defaultValue = cleanDefault(param2.defaultValue());
							if (!defaultValue.equals("")) {
								waldParam.setDefault(defaultValue);
							}
							waldParam.setType(nm);
						} else if (annotation2 instanceof PathVariable) {
							PathVariable param2 = (PathVariable) annotation2;
							QName nm = convertJavaToXMLType(paramType);
							Param waldParam = wadlRequest.addNewParam();
							waldParam.setName(param2.value());
							waldParam.setStyle(ParamStyle.TEMPLATE);
							waldParam.setRequired(true);
							waldParam.setType(nm);
						}
					}
				}
				if (!wadlRequest.getParamList().isEmpty()) {
					wadlMethod.setRequest(wadlRequest);
				}

				// Response
				if (!mediaTypes.isEmpty()) {
					Response wadlResponse = wadlMethod.addNewResponse();
					Class methodReturn = handlerMethod.getReturnType().getClass();
					ResponseStatus status = handlerMethod.getMethodAnnotation(ResponseStatus.class);
					if (status == null) {
						List statusues = wadlResponse.getStatus();
						if (statusues == null) {
							statusues = new LinkedList<>();
							statusues.add((long) (HttpStatus.OK.value()));
							wadlResponse.setStatus(statusues);
						} else {
							statusues.add((long) (HttpStatus.OK.value()));
						}
					} else {
						HttpStatus httpcode = status.value();
						wadlResponse.getStatus().add((long) httpcode.value());
					}

					for (MediaType mediaType : mediaTypes) {
						Representation wadlRepresentation = wadlResponse.addNewRepresentation();
						wadlRepresentation.setMediaType(mediaType.toString());
					}
				}
			}

		}
		return appdoc.xmlText();
	}

	private QName convertJavaToXMLType(Class<?> type) {
		QName nm = new QName("");
		String classname = type.toString();
		if (classname.indexOf("String") >= 0) {
			nm = new QName(xs_namespace, "string", "xs");

		} else if (classname.indexOf("Integer") >= 0) {
			nm = new QName(xs_namespace, "int", "xs");
		}
		return nm;
	}

	private Resource createOrFind(String uri, Resources wadResources) {
		List current = wadResources.getResourceList();
		for (Resource resource : current) {
			if (resource.getPath().equalsIgnoreCase(uri)) {
				return resource;
			}
		}
		Resource wadlResource = wadResources.addNewResource();
		return wadlResource;
	}

	private String getBaseUrl(HttpServletRequest request) {
		String requestUri = request.getRequestURI();
		return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
	}

	private String cleanDefault(String value) {
		value = value.replaceAll("\t", "");
		value = value.replaceAll("\n", "");
		return value;
	}
}


打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据