DevOps DevOps
产品简介
产品安装
快速入门
使用指南
开发指南
FAQ
6.7更新说明
  • DevOps更新说明
  • Controller接口改造说明
  • Controller实现类改造说明
  • 多部分文件参数说明
  • MultipartFormDataInput更新说明
  • Resteasy 中的使用
  • RESTful说明
  • 一、请求方法规范
  • 二、请求与响应体规范
  • 三、注解使用规范
  • 四、其他规范

# DevOps更新说明

# Controller接口改造说明

# 一、注解改造

原代码:

@Path("/api/uc/apply-users")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Api(description = "申请用户管理对外接口")

改造后:

import org.springframework.http.MediaType;

@RequestMapping(value = "/api/uc/apply-users", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
@Api(tags="IUserController【对应类名】",description = "申请用户管理对外接口")

# 二、方法改造

Get类型源码:

@GET
@ApiOperation("查询申请用户")
PageResultList<ApplyUser> queryApplyUsers(@QueryParam("empName") @ApiParam("申请用户名称") String empName,
@QueryParam("companyName") @ApiParam("公司名称") String companyName,
@QueryParam("pageIndex") @ApiParam("分页索引") int pageIndex,
@QueryParam("pageSize") @ApiParam("分页大小") int pageSize) throws Exception;

改造后:

@GetMapping
@ApiOperation("查询申请用户")
PageResultList<ApplyUser> queryApplyUsers(@RequestParam(name = "empName", required = false) @ApiParam("申请用户名称") String empName,
@RequestParam(name = "companyName", required = false) @ApiParam("公司名称") String companyName,
@RequestParam(name = "pageIndex", required = false, defaultValue = "0") @ApiParam("分页索引") int pageIndex,
@RequestParam(name = "pageSize", required = false, defaultValue = "0") @ApiParam("分页大小") int pageSize) throws Exception;

说明: 1、有path映射时 如 @Path("/{applyId}") 把path加到value参数里 @GetMapping(value = "/{applyId}") 2、参数为基本数据类型时,推荐加上 defaultValue = "基本数据类型初值" 因为现在使用Spring Restful框架参数默认必填的(可以加上非必填,但是值没有初始化),以前Resteasy是非必填的,所以有可能使用的时候没传参数,默认用的初值,所以现在推荐手动赋上初值。 3、详细改造映射【RESTful API 开发手册 - 请求与响应规范.md】

Post类型源码:

@Path("/actions/create")
@POST
@ApiOperation("新增申请用户")
ApplyUser createApplyUser(@ApiParam("用户申请信息") ApplyUser applyUser) throws Exception;

改造后:

@PostMapping(value = "/actions/create")
@ApiOperation("新增申请用户")
ApplyUser createApplyUser(@RequestBody @ApiParam("用户申请信息") ApplyUser applyUser) throws Exception;

Put类型源码:

@Path("/{applyId}")
@PUT
@ApiOperation("更新用户申请信息")
@Permission("admin_apply_user_edit")
ApplyUser modifyApplyUser(@ApiParam("用户申请信息") ApplyUser applyUser) throws Exception;

改造后:

@PutMapping(value = "/{applyId}")
@ApiOperation("更新用户申请信息")
@Permission("admin_apply_user_edit")
ApplyUser modifyApplyUser(@RequestBody @ApiParam("用户申请信息") ApplyUser applyUser) throws Exception;

Delete类型源码:

@Path("/{applyId}")
@DELETE
@ApiOperation("删除申请用户")
@Permission("admin_apply_user_remove")
ApplyUser removeApplyUser(@PathParam("applyId") @ApiParam("申请ID") String applyId) throws Exception;

改造后:

@PutMapping(value = "/{applyId}")
@ApiOperation("更新用户申请信息")
@Permission("admin_apply_user_edit")
ApplyUser modifyApplyUser(@RequestBody @ApiParam("用户申请信息") ApplyUser applyUser) throws Exception;

# Controller实现类改造说明

# 一、注解改造

@Controller改成@RestController

@Controller
public class ApplyUserController implements IApplyUserController
@RestController
public class ApplyUserController implements IApplyUserController

# 多部分文件参数说明

MultipartFormDataInput改造需要具体情况具体分析

MultipartFormDataInput改成@RequestParam MultipartFile或者List

# MultipartFormDataInput更新说明

# Resteasy 中的使用

在Resteasy中,你可以使用 MultipartFormDataInput 来接收多部分请求,并通过 InputPart 来访问其中的具体部分。例如:

@POST  
@Path("/upload")  
@Consumes(MediaType.MULTIPART_FORM_DATA)  
public Response uploadFile(MultipartFormDataInput input) {  
    Map<String, List<InputPart>> uploadForm = input.getFormDataMap();  
    List<InputPart> inputParts = uploadForm.get("file");  
    for (InputPart inputPart : inputParts) {  
        try {  
            // MultipartBodyDataPart bodyDataPart = (MultipartBodyDataPart) inputPart.getBody(MultipartBodyDataPart.class, null);  
            // InputStream inputStream = bodyDataPart.getInputStream();  
            InputStream inputStream = inputPart.getBody(InputStream.class, null);
            // 处理文件流 获取文件名称
            MultivaluedMap<String, String> headers = attachmentPart.getHeaders();
			String[] contentDispositions = headers.getFirst("Content-Disposition").split(";");
			String fileName = null;
			for (String dispositon : contentDispositions) {
				if (dispositon.contains("filename=")) {
					fileName = CommonUtil.splitExcludeBlank(CommonUtil.urlDecode(dispositon), "[=\"]").toArray(new String[0])[1];
					break;
				}
			}
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
    return Response.ok().build();  
}

在这个例子中,我们通过 MultipartFormDataInput 获取了表单数据,并通过 InputPart 访问了名为 "file" 的上传文件部分。

# 改为 Restful(Spring)中的使用

MultipartFile的名称很重要,需要和上传的请求体里一致才能获取到。

在Spring的Restful接口中,你可以使用 MultipartFile 来接收上传的文件。例如:

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)  
public ResponseEntity<String> uploadFile(@RequestParam("file") @ApiParam("文件") MultipartFile file) {  
    try {  
        // 获取输入流
        InputStream attachmentInputStream = file.getInputStream();
        String fileName = file.getOriginalFilename();
        // 处理文件,例如保存到磁盘  
        file.transferTo(new File("path/to/destination/" + file.getOriginalFilename())); 
        return ResponseEntity.ok("File uploaded successfully");  
    } catch (IOException e) {  
        e.printStackTrace();  
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Could not upload the file");  
    }  
}

多个文件用list接收,为了通用我们改造的时候直接用List

public ResponseEntity<String> uploadFile(@RequestParam @ApiParam("多文件") List<MultipartFile> files)

在这个例子中,我们使用 @RequestParam 注解来指定请求参数 "file" (不写也可以,但是对象名字得一致) 应该被映射到 MultipartFile 类型的参数上。然后我们可以使用 MultipartFile 提供的方法来处理上传的文件。

MultipartFile的名称很重要,需要和上传的请求体里一致才能获取到。

在Spring的Restful接口中,你可以使用 MultipartFile 来接收上传的文件。例如:

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)  
public ResponseEntity<String> uploadFile(@RequestParam("file") @ApiParam("文件") MultipartFile file) {  
    try {  
        // 获取输入流
        InputStream attachmentInputStream = file.getInputStream();
        String fileName = file.getOriginalFilename();
        // 处理文件,例如保存到磁盘  
        file.transferTo(new File("path/to/destination/" + file.getOriginalFilename())); 
        return ResponseEntity.ok("File uploaded successfully");  
    } catch (IOException e) {  
        e.printStackTrace();  
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Could not upload the file");  
    }  
}

多个文件用list接收,为了通用我们改造的时候直接用List

public ResponseEntity<String> uploadFile(@RequestParam @ApiParam("多文件") List<MultipartFile> files)

在这个例子中,我们使用 @RequestParam 注解来指定请求参数 "file" (不写也可以,但是对象名字得一致) 应该被映射到 MultipartFile 类型的参数上。然后我们可以使用 MultipartFile 提供的方法来处理上传的文件。

# 关联的参数名称不确定时

通过 MultipartHttpServletRequest multipartHttpServletRequest multipartHttpServletRequest会自动将传入的表单拆成两部分分别放入文件和非文件参数里。

对于文件类型 multipartHttpServletRequest.getMultiFileMap();

可以遍历map来实现

Map<String, List<MultipartFile>> multiFileMap = multipartHttpServletRequest.getMultiFileMap();
for (Entry<String, List<MultipartFile>> entry:multiFileMap.entrySet()) {
	workitemService.addWorkitemAttachments(workitemId, entry.getKey(), entry.getValue());
}
# 如果还包含非文件类型但参数名不确定,或者在某一范围时

multipartHttpServletRequest.getParameterMap()

Map<String, String[]> multiFileMap = multipartHttpServletRequest.getParameterMap();
String[] data = multipartHttpServletRequest.getParameterValues("data");#可以根据key获取String数组 一般默认[0]即可 

如果请求表单里既有文件又有非文件类似json字符串时 如果已知非文件的key值建议如下实践 例:构建介质上传接口,请求内容

data: {"username":null,"password":null,"repo":null,"groupId":null,"artifactId":"testfile","version":"1.0.0","alias":"file1","classifier":null,"fileName":"file.txt","projectId":"21","artifactRepositoryId":"1","artifactCategory":"obj","fileSize":5891,"componentId":"21","systemId":"2","needInsertDB":true,"repoUrl":"http://10.15.15.133:8081/repository/DEMO072501-demoJar/"}
file: (binary)

通过字符串文本的key即可获取对应内容,而不是再请求体里在解析获取

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	@ApiOperation("介质上传")
	@Permission("project_artifact_upload")
	void uploadArtifact(@RequestParam @ApiParam("附件") List<MultipartFile> file,
			@RequestParam("data") @ApiParam("介质信息") String dataJson) throws Exception;

# RESTful说明

# 一、请求方法规范

# POST 请求

  • 使用 @PostMapping 注解定义 POST 请求的 URI。

  • 使用 @MultiRequestBody注解接收请求体中的 JSON 数据。

  • 示例:

    @PostMapping("/versions")  
    public ResponseEntity<?> createVersion(@MultiRequestBody Version version) {  
        // 处理逻辑...  
        return ResponseEntity.ok().build();  
    }
    

# PUT 请求

  • 使用 @PutMapping 注解定义 PUT 请求的 URI。

  • 与 POST 请求类似,使用 @MultiRequestBody注解接收请求体中的 JSON 数据。

  • 示例:

    @PutMapping("/versions/{versionId}")  
    public ResponseEntity<?> modifyVersion(@PathVariable Long versionId, @RequestBody Version version) {  
        // 处理逻辑...  
        return ResponseEntity.ok().build();  
    }
    

# DELETE 请求

  • 使用 @DeleteMapping 注解定义 DELETE 请求的 URI。

  • 对于简单的 DELETE 请求,通常不需要 @MultiRequestBody注解,而是使用 URI 参数或请求参数来标识要删除的资源。

  • 示例:

    @DeleteMapping("/versions/{versionId}")  
    public ResponseEntity<?> removeVersion(@PathVariable Long versionId) {  
        // 处理逻辑...  
        return ResponseEntity.ok().build();  
    }
    

# GET 请求

  • 使用 @GetMapping 注解定义 GET 请求的 URI。

  • 使用 @RequestParam 注解接收查询参数。

  • required = false 非必填

  • defaultValue = "" 预设默认值

  • 示例:

    @GetMapping("/versions")  
    public ResponseEntity<List<Version>> queryVersionsByCriteria(  
            @RequestParam(name = "versionName", required = false, defaultValue = "") String versionName,  
            // 其他参数...  
    ) {  
        // 处理逻辑...  
        return ResponseEntity.ok(versions);  
    }
    

# 二、请求与响应体规范

  1. 请求体
    • 请求体应使用 JSON 格式。
    • 使用 @RequestBody 注解接收请求体中的 JSON 数据,并将其反序列化为 Java 实体类对象。
  2. 响应体
    • 响应体应使用 JSON 格式。
    • 对于成功的请求,通常返回 HTTP 状态码 200,并在响应体中返回相应的数据。
    • 对于失败的请求,应返回适当的 HTTP 状态码(如 400、404、500 等),并在响应体中返回错误信息。

# 三、注解使用规范

  • 使用 @RestController 注解标识控制器类。

  • 使用 @RequestMapping(或其变体如 @GetMapping、@PostMapping 等)注解定义 URI 和 HTTP 方法。

  • 使用 @PathVariable 注解从 URI 中提取路径变量。

  • 使用 @RequestParam 注解从查询参数中提取参数值。

  • 使用 @RequestBody 注解接收请求体中的 JSON 数据。

  • 使用 @ResponseBody(但通常在 @RestController 下的方法上不需要显式使用,因为 @RestController 默认包含了 @ResponseBody)注解表示该方法的返回值将作为响应体返回给客户端。

  • 参考如下 MediaType.APPLICATION_JSON_UTF8_VALUE过时了可以用 MediaType.APPLICATION_JSON_VALUE代替

    @Api(tags = "Version管理")
    @RestController
    @RequestMapping(value = "/api/rest/service/versions", consumes = { MediaType.APPLICATION_JSON_UTF8_VALUE }, produces = {
            MediaType.APPLICATION_JSON_UTF8_VALUE })
    

# 四、其他规范

  • 确保 API 的 URI 设计清晰、简洁,并遵循 RESTful 风格。

  • 使用 HTTP 状态码来表示请求的成功或失败。

  • 在 API 文档中清晰描述每个 API 的 URI、请求方法、请求参数、响应数据和错误码等信息。

    如 @ApiParam("")

    @ApiOperation("条件查询字典类型,分页展示")
    @GetMapping
    public PageResultList<DictType> queryDictTypesByCriteria(
    @ApiParam("字典类型编码") @RequestParam(name = "code", required = false) String code,
    @ApiParam("字典类型名称") @RequestParam(name = "name", required = false) String name,
    @ApiParam("父字典类型ID") @RequestParam(name = "parentId", required = false) String parentId,
    @ApiParam("字典类型层级") @RequestParam(name = "levels", required = false) String levels,
    @ApiParam("每页条数") @RequestParam(name = "pageSize", required = false, defaultValue = "0") int pageSize,
    @ApiParam("当前页数") @RequestParam(name = "pageIndex", required = false, defaultValue = "0") int pageIndex,
    @ApiParam("排序字段:多字段,分割") @RequestParam(name = "orderFields", required = false) String orderFields,
    @ApiParam("排序规则:ASC OR DESC") @RequestParam(name = "orderDirection", required = false) String orderDirection) throws Exception {
        return dictTypeService.queryDictTypesByCriteria(code, name, parentId, levels, pageSize, pageIndex, orderFields, orderDirection);
    }
    
  • 遵循良好的编码习惯和代码规范,确保代码的可读性和可维护性。

resteasy与springmvc注解映射

resteasy spring mvc 说明
@Path @RequestMapping(GetMapping,PostMapping, PutMapping, DeleteMapping)的value值 path
@GET,POST, PUT, DELETE @GetMapping,PostMapping, PutMapping, DeleteMapping method
@PathParam,不是必填 @PathVariable,默认是必填 path param
@HeaderParam,不是必填 @RequestHeader,默认是必填 head param
@QueryParam,不是必填 @RequestParam,默认是必填 query param
@FormParam,不是必填 @RequestParam,默认是必填 form param
没有注解 @RequestBody,默认是必填
@SdoRequestBody(6.7更新eos底层时新增的自定义注解 用于兼容Sdo实体,自动映射Interface对应的实现类)
body param
@JSONParam @MultiRequestBody 多body param
@Context,类HttpServletRequest或者HttpServletResponse 没有,直接使用类HttpServletRequest或者HttpServletResponse 获取HttpServletRequest或者HttpServletResponse(下载用)
MultipartFormDataInput类型的参数@Consumes(MediaType.MULTIPART_FORM_DATA) @RequestParam MultipartFile或者List类型的参数, @PostMapping(value = "/actions/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) 上传

← 坏链接处理说明 服务集成配置 →