webService接口的荆棘之路

醉酒当歌 提交于 2020-01-20 03:24:27

hello,我又回来了,有没有想我啊,哈哈~~
不和大家扯皮,我今天就分享一下,我的webService的荆棘之路!!!
今天领导给我发布一个任务,任务是一个文档,如图所示
~~在这里插入图片描述
这个一看我以为是正常的webService风格的接口,一般的webService接口不都是http格式请求,可是今天的这个不是,这是要做一个API请求,我一听API请求,为什么不传json,要传xml???
最后才知道客户,就是这样要求的,没有办法,那好咱们也不用想的太多,是祸躲不过,直接开干!!

1.请求参数

既然请求参数也是xml,那么我们就需要建立一个承载体,也就是实体类,代码如下:



import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;

@XmlRootElement(name = "requestBody")
public class StatisticsInfoDailyRequest {
    @NotBlank(message = "hospId不能是空")
    private String hospId;
    //@NotBlank(message = "wardId不能是空")
    private String wardId;
    //@NotBlank(message = "deptId不能是空")
    private String deptId;
    //@NotNull(message = "statisticsDate不能是空")
    private Date statisticsDate;

    public String getHospId() {
        return hospId;
    }

    public void setHospId(String hospId) {
        this.hospId = hospId;
    }

    public String getWardId() {
        return wardId;
    }

    public void setWardId(String wardId) {
        this.wardId = wardId;
    }

    public String getDeptId() {
        return deptId;
    }

    public void setDeptId(String deptId) {
        this.deptId = deptId;
    }

    public Date getStatisticsDate() {
        return statisticsDate;
    }

    public void setStatisticsDate(Date statisticsDate) {
        this.statisticsDate = statisticsDate;
    }
}

这一点我一共使用了3个注解

  • 1.@XmlRootElement
  • 2.@NotBlank
  • 3.@NotNull
  • 4.message = “”
    顺便给大家讲一下这个注解的意思,知道的大神权当我放屁~~~~~~~~~~
  • 1 XmlRootElement 便于对象与xml文件之间的转换,有了这个注解,就可以实现对象和xml之间的互转,如果传递过来的是xml,可以直接自动转换为对象
  • 2 NotBlank 判断这个字段是否为null 这个比较坑 只能判断字符串
  • 3 NotNull 这个是可以判断时间等其他类型的
  • 4 message 是如果当这个字段为null时,你需要返回一个字符,比如一句话“不能为null”

2.返回参数

返回参数就比较复杂了,因为我们需要包装好几层,如下:

<responseInfo>
    <responseBody>
        <statisticsList>
            <statisticsInfo>
                <deptId></deptId>
                <hospId>ddae6162af1747dba538383b37eb64d3</hospId>
                <statisticsDate>2020-01-18 14:54:00</statisticsDate>
                <statisticsKey>06</statisticsKey>
                <statisticsType>1</statisticsType>
                <statisticsValue>7</statisticsValue>
                <wardId>80e6da44d1d84aed8f67d33d027ea7fc</wardId>
            </statisticsInfo>
        </statisticsList>
    </responseBody>
    <responseHeader>
        <code>0</code>
        <msg>查询成功</msg>
    </responseHeader>
</responseInfo>

也就是我的对象是在里面的第四层,也就是我需要包裹三层,好崩溃!!!!
但是我却忘记了一个技能 那就是注解 哈哈哈~~~
这个时候就需要用到 XmlElementWrapper注解了
我可以带大家看一下源码分析
在这里插入图片描述
我们看1处 这个是没有加XmlElementWrapper注解前是这个,但是加了之后 就多了一层之后2处可以看出来多包装了一层。
让大家看一下代码



import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;

@XmlRootElement(name = "responseBody")
@XmlAccessorType(XmlAccessType.FIELD)
public class StatisticsInfoDailyBody {
    @XmlElementWrapper(name = "statisticsList")
    private List<StatisticsInfoDailyDto> statisticsList;

    public List<StatisticsInfoDailyDto> getStatisticsList() {
        return statisticsList;
    }

    public void setStatisticsList(List<StatisticsInfoDailyDto> statisticsList) {
        this.statisticsList = statisticsList;
    }

    public StatisticsInfoDailyBody(List<StatisticsInfoDailyDto> statisticsList) {
        this.statisticsList = statisticsList;
    }

    public StatisticsInfoDailyBody() {
    }
}

给list集合加上XmlElementWrapper注解之后 外层的list标签就不用在去建一个dto了,是不是很舒服 哈哈哈~~~~

  • XmlAccessorType注解说明
    XmlAccessType.FIELD:映射这个类中的所有字段到XML
    XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML
    XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)
    XmlAccessType.NONE:不映射


import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="responseHeader")
public class ResponseHeader {

    private String code;
    private String msg;
    
    public ResponseHeader() {
        super();
    }
    public ResponseHeader(String code, String msg) {
        super();
        this.code = code;
        this.msg = msg;
    }
    @XmlElement(name="code")
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    
    @XmlElement(name="msg")
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    
}
  • XmlElement 注解说明
  • 字段,方法,参数级别的注解。该注解可以将被注解的(非静态)字段,或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。
  • 参数 name :用于指定映射时的节点名称,指定生成元素的名字,若不指定,默认使用方法名小写作为元素名。
  • 参数 namespace : 指定映射时的节点命名空间
  • 参数 required : 字段是否必须,默认为false
  • 参数 nillable : 是否处理空数据,默认为false
  • 参数 type : 定义该字段或属性的关联类型

这一点其实可以使用XmlAccessorType注解 但是是之前的老代码 没有去动它。
最后就是最外层的ResponseInfo





import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "responseInfo")
@XmlAccessorType(XmlAccessType.FIELD)
public class StatisticsInfoDailyResponseInfo {
    private StatisticsInfoDailyBody responseBody;
    private ResponseHeader responseHeader;

    public StatisticsInfoDailyResponseInfo() {
    }

    public StatisticsInfoDailyResponseInfo(ResponseHeader responseHeader) {
        this.responseHeader = responseHeader;
    }

    public StatisticsInfoDailyResponseInfo(ResponseHeader responseHeader, StatisticsInfoDailyBody responseBody) {
        this.responseBody = responseBody;
        this.responseHeader = responseHeader;
    }

    public StatisticsInfoDailyBody getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(StatisticsInfoDailyBody responseBody) {
        this.responseBody = responseBody;
    }

    public ResponseHeader getResponseHeader() {
        return responseHeader;
    }

    public void setResponseHeader(ResponseHeader responseHeader) {
        this.responseHeader = responseHeader;
    }
}

最关键的一点就是 你参数的命名 就是你返回时 的参数的命名。

//如果responseInfo中的返回信息头 你参数命名为private ResponseHeader header;
那么返回的结果就是
 <header>
        <code>0</code>
        <msg>????</msg>
</header>
//如果是private ResponseHeader responseHeader; 自己定义
<responseHeader>
        <code>0</code>
        <msg>????</msg>
</responseHeader>

最后就是最关键的一点 控制器 ,代码如下

@RestController("PatientController")
@Scope("prototype")
@RequestMapping("/patient")
public class PatientController {
    @Autowired
    private PatientInfoBusiness patientInfoBusiness;

    @Sign(auth=false)
    @Permission(auth=false)
    @RequestMapping(value = "/ws/getStatisticsInfo", method = RequestMethod.POST,produces = {"application/xml;charset=UTF-8"})
    public String getStatisticsInfo(@RequestBody @Valid StatisticsInfoDailyRequest requestInfo, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            String collect = bindingResult.getAllErrors().parallelStream().map(i -> i.getDefaultMessage()).collect(Collectors.joining(";"));
            return new ResponseInfo(new ResponseHeader(MessageCode.PARAM_WRONG.getCode(), collect), null).toXml();
        }
        try {
            List<StatisticsInfoDailyDto> statisticsInfo = this.patientInfoBusiness.getStatisticsInfo(requestInfo);
            ResponseHeader header = new ResponseHeader(MessageCode.SUCCESS.getCode() + "", "查询成功");
            String responseBody = XmlHelper.listObj2xmlStr(statisticsInfo, "statisticsList", "statisticsInfo");
            ResponseInfo responseInfo = new ResponseInfo(header, responseBody);
            return responseInfo.toXml();
        } catch (BusinessException e)
        {
            return new ResponseInfo(new ResponseHeader(e.getCode() + "", e.getMessage()), null).toXml();
        } catch (Exception e)
        {
            return new ResponseInfo(new ResponseHeader(MessageCode.EXCEPTION_EXECUTE_FAIL.getCode() + "", "getLisSampleInfo  执行异常"), null).toXml();
        }
    }
}
  • produces 代表出参返回的是什么类型
  • @Valid 就是和NotBlank 一起使用的 验证字段是否为空
  • BindingResult 里面装的就是验证结果 如果没有 那就是验证成功
    如图 我们测试的结果 没有传 hospId
    在这里插入图片描述
    剩下就是拼接xml 返回完整结构的xml
    今天 的分享就到这里 如果有什么疑问 欢迎交流 !!!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!