面向服务的软件系统实验一
《面向服务的软件系统》实验报告
——实验一:服务构件/服务系统的设计与实现
姓名: 石卓凡 学号: 120L021011
- 实验1 基于Apache CXF框架的服务开发环境搭建
- 项目中的pom.xml中的dependencies是什么?有什么作用?
是什么
Pom.xml是项目对象模型,属于Maven项目中的文件,使用xml表示,可以用于管理源代码,配置文件,开发者信息,项目的依赖关系等
Pom.xml的其中dependencies内部的元素都是项目中需要被引进的依赖,被maven管理,即通过<dependencies>可以给出Maven项目所依赖的第三方类库。而dependencies里面有若干个<dependency>,而dependency标签有含有多个属性比如:
groupId:公司或者组织的唯一标志,并且配置时生成的路径也是由此生成,
artifactId本项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的
type,打包类型,默认jar
scope,被依赖的Maven构件在classpath中的可访问范围
optional,当前Maven项目的构件被其他项目依赖,此处被依赖的Maven构件相对于其他项目来说是不必须的
exclusions,将一个被依赖的Maven构件中的部分类库,从classpath中去掉
给出一个简单实例:
<project>
…
<dependencies>
<dependency>
<!–组织ID–>
<groupId></groupId>
<!–项目ID–>
<artifactId></artifactId>
<!–版本号–>
<version></version>
<!–依赖类型–>
<type></type>
<!–类别(类目)–>
<classifier></classifier>
<!–指定依赖的范围–>
<scope></scope>
<!–指定本地jar路径,和scope一起使用–>
<systemPath></systemPath>
<!–排除依赖列表–>
<exclusions>
<exclusion>
<artifactId></artifactId>
<groupId></groupId>
</exclusion>
</exclusions>
<!–指定是否需要被依赖–>
<optional></optional>
</dependency>
</dependencies>
…
</project>
作用:
通过dependecies管理项目对第三方包的依赖,利用元素可以将包的依赖下载到本地仓库并以此给项目进行使用,让项目得到构建和部署
比如:
<**dependency**>
<**groupId**>com.baomidou</**groupId**>
<**artifactId**>mybatis-plus-boot-starter</**artifactId**>
<**version**>3.5.2</**version**>
</**dependency**>
会让maven自动去下载mybatis-plus-boot-starter的依赖,其中版本要求为3.5.2,下载之后会自动管理和使用。项目中原本对于mybatis-plus-boot-starter爆红的地方就会解决,变为正常
- 服务接口中方法参数中@webparam注解用与不用的实验结果是否会有变化?
@webparam是什么
WebParam是webservice里面的注解,表示方法的参数名指定为一个名称
如果不使用@WebParam的注解,则方法参数的name默认为arg0,arg1,arg2……
而返回值的name默认为return
比如:
< xs:element minOccurs=”0” name=”arg0” />
< xs:element minOccurs=”0” name=”return” />
如果使用了@WebParam的注解比如@WebParam(name=”password”)后,在wsdl中看到的参数名称就成为了password
比如:
< xs:element minOccurs=”0” name=”password” />
变化:
1控制台返回结果一致
加入WebParam注解和不加入WebParam注解均成功运行
且二者控制台返回结果一致
- wsdl文档中结果不一致
(1)public Reader getReader(String name, String password)
当不加入注解时候可以发现,getReader方法中的参数名叫做arg0,arg1没有实际意义,仅表示参数顺序
(2)public Reader getReader(@WebParam(name=“name”) String name, @WebParam(name = “password”) String password)
当加入注解时候可以发现,getReader方法中的参数名叫做name,password,为对应的@WebParam中给定的参数名称
- 方法实现中@webservice注解中的参数endpointInterface和serviceName分别代表了什么?
@WebService(endpointInterface = “main.IReaderService”,serviceName = “readerService”)
@WebService注解:作用于具体类,可以通过这个注解利用endpoint发布一个web服务
endpointInterface:
用于指定服务的接口类的路径,指定做SEI服务端口接口,如果指定了此限定名,那么会使用该服务端点接口来确定抽象 WSDL 约定
在Lab1中的endpointInterface = “main.IReaderService”
“main.IReaderService”代表了指定服务接口是main文件夹下面的IReaderService接口,路径为main.IReaderService
serviceName:
指定对外发布的服务名。默认值值为 Java 类的简单名称+Service。
在Lab1中serviceName = “readerService”
wsdl对应的显示如下:
- 实验2 基于SpringBoot框架的服务开发环境搭建
- 注解@RequestParam和@PathVariable分别表示什么?
@RequestParam:
作用:
请求中的指定名称的参数传递给控制器中的形参赋值,接收的参数是请求url的QueryString(HTTP协议中的Request参数)中(不同于@Requestbody接收请求体中的参数)
举例子:
http://localhost:8080/user?id=1
对应代码
@GetMapping(“/user”)
public String testRequestParam(@RequestParam Integer id) {
System.out.println(“获取到的id为:” + id);
return “success”;
}
语法:
@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
value:参数名
required:默认为true,表示该请求路径中是否必须包含这个参数
开启了true之后,如果 value 属性值没有对应上jsp中 name 值则会直接报400错误
defaultValue:默认参数值,如果没有传该参数,就使用默认值
举例子:
(@RequestParam(value=”password”,required=true,defaultValue=”123456”)
@PathVariable:
作用:
接收到参数是来自url变量,获取 url 参数
可以将URL中占位符参数{x}绑定到处理器类的方法形参中@PathVariable(“x“)
举例子localhost:8080/user/1
@GetMapping(“/user/{id}”)
public String testRequestParam(@PathVariable Integer id) {
System.out.println(“获取到的id为:” + id);
return “success”;
}
语法:@PathVariable(value=”参数名”,required=”true/false”,name=””)
name-别名名称
Value要绑定的路径变量名称
required-指示路径变量是否为必需
Lab1中:
原代码为:
@RequestMapping(value = “/hallo/{id}”,method = RequestMethod.GET)
public TestEntity say1(@RequestParam(value = “qid”,required = true) String qid, @PathVariable(“id”) String id){
return new TestEntity(qid, id);
}
@RequestParam接收pid
@PathVariable接收id
访问路径http://localhost:8080/hallo/1?pid=2
但是这里的@RequestParam与@PathVariable同时使用,无法读取到@RequestParam想要解释的pid,于是会报400错误,提示pid未接收到
将qid设定为非必须且给定默认值为1则解决问题可以运行
@RequestMapping(value = “/hallo/{id}”,method = RequestMethod.GET)
public TestEntity say1(@PathVariable(“id”) String id,@RequestParam(value = “qid”,required = false) String qid){
System.out.println(“qid = “ + qid);
return new TestEntity(“1”,id);
}
结果:
得到400报错
原因:
同上一问,源代码中@RequestParam(value = “qid”,required = true)要求提供qid的HTTP请求参数,但是未提供,因此报错
解决方案:
在去掉@RequestParam之后
将pid默认”1”
可以正常显示(测试改端口8888,对结论无影响)
- 结合本次实验感受,试分析基于服务的软件系统与你以往做过的软件有何区别?可以从软件结构、开发过程、调试方法等方面阐述。
区别:
(1)之前学习和使用的是面向对象和面向接口,如今是面向服务service,用面向服务的方法去管理服务之间的发生的事情。
直观上来说,之前做的程序,要实现投票系统,关注的是投票人对象,匿名票对象以及对象之间的关系和互相调用互动
现在面向服务的软件系统,比如如果要实现springboot的web网页,需要划分为entity,mapper,service,controller基本四层,其中要根据业务需求重点考虑好service服务的设计,然后是controller控制层
- 之前使用的是基础JAVA语法,如今要启动框架,站在前人的肩膀上来看世界,比如直接使用springboot和springcloud框架,需要了解各自框架的如何使用,其中有哪些注解,框架的格式,框架的配置文件内容等等
- 基于服务的软件系统在制作软件的过程中,设计时还需要考虑更加全面的方面,比如说如果使用SOA的体系结构,就要考虑松散耦合,粗粒度服务,标准化接口,在设计uml时候也需要考虑将服务使用者和服务提供者在服务实现和客户如何使用服务方面隔离开来
- 对于微服务的知识点,也让我认识到了区别所在,之后需要关注的内容还得关注于高并发问题集群问题,比如之后用springboot写出了一个软件,可以用springcloud变成高性能分布式,还可以用docker打包镜像然后k8s部署到多台云服务器,以此来解决高并发问题。以前设计的软件用户量太小不需要考虑