精华内容
下载资源
问答
  • 基于springboot创建RESTful风格接口

    千次阅读 2018-04-27 13:59:50
    基于springboot创建RESTful风格接口 RESTful API风格 特点: URL描述资源 使用HTTP方法描述行为。使用HTTP状态码来表示不同的结果 使用json交互数据 RESTful只是一种风格,并不是强制的标准 一、查询...

    基于springboot创建RESTful风格接口

    RESTful API风格

    restfulAPI.png

    特点:

    1. URL描述资源
    2. 使用HTTP方法描述行为。使用HTTP状态码来表示不同的结果
    3. 使用json交互数据
    4. RESTful只是一种风格,并不是强制的标准

    REST成熟度模型.png

    一、查询请求

    1.编写单元测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        @Before
        public void setup() {
    
            mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    
        //查询
        @Test
        public void whenQuerySuccess() throws Exception {
            String result = mockMvc.perform(get("/user")
                    .param("username", "jojo")
                    .param("age", "18")
                    .param("ageTo", "60")
                    .param("xxx", "yyy")
    //              .param("size", "15")
    //              .param("sort", "age,desc")
                    .contentType(MediaType.APPLICATION_JSON_UTF8))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.length()").value(3))
                    .andReturn().getResponse().getContentAsString();//将服务器返回的json字符串当成变量返回
    
            System.out.println(result);//[{"username":null},{"username":null},{"username":null}]
        }
    }
    

    2.使用注解声明RestfulAPI

    常用注解

    @RestController 标明此Controller提供RestAPI
    @RequestMapping及其变体。映射http请求url到java方法
    @RequestParam 映射请求参数到java方法的参数
    @PageableDefault 指定分页参数默认值
    @PathVariable 映射url片段到java方法的参数
    在url声明中使用正则表达式
    @JsonView控制json输出内容
    

    查询请求:

    @RestController
    public class UserController {
    
        @RequestMapping(value="/user",method=RequestMethod.GET)
        public List<User> query(@RequestParam(name="username",required=false,defaultValue="tom") String username){
            System.out.println(username);
            List<User> users = new ArrayList<>();
            users.add(new User());
            users.add(new User());
            users.add(new User());
            return users;
        }
    }
    

    ①当前端传递的参数和后台自己定义的参数不一致时,可以使用name属性来标记:

    (@RequestParam(name="username",required=false,defaultValue="hcx") String nickname
    

    ②前端不传参数时,使用默认值 defaultValue=”hcx”

    ③当查询参数很多时,可以使用对象接收

    ④使用Pageable作为参数接收,前台可以传递分页相关参数
    pageSize,pageNumber,sort;
    也可以使用@PageableDefault指定默认的参数值。

    @PageableDefault(page=2,size=17,sort="username,asc")
    //查询第二页,查询17条,按照用户名升序排列
    

    3.jsonPath表达式书写

    github链接:https://github.com/json-path/JsonPath

    jsonpath表达式.png

    打包发布maven项目.png

    二、编写用户详情服务

    @PathVariable 映射url片段到java方法的参数
    在url声明中使用正则表达式
    @JsonView控制json输出内容

    单元测试:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class UserControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        @Before
        public void setup() {
    
            mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    
        //获取用户详情
        @Test
        public void whenGetInfoSuccess() throws Exception {
            String result = mockMvc.perform(get("/user/1")
                    .contentType(MediaType.APPLICATION_JSON_UTF8))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.username").value("tom"))
                    .andReturn().getResponse().getContentAsString();
    
            System.out.println(result); //{"username":"tom","password":null}
    
        }
    

    后台代码:

    @RestController
    @RequestMapping("/user")//在类上声明了/user,在方法中就可以省略了
    public class UserController {
        @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
        public User getInfo(@PathVariable String id) {
                User user = new User();
                user.setUsername("tom");
                return user;
            }
    

    当希望对传递进来的参数作一些限制时,可以使用正则表达式:

    //测试提交错误信息
    @Test
    public void whenGetInfoFail() throws Exception {
        mockMvc.perform(get("/user/a")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().is4xxClientError());
    }
    

    后台代码:

    @RequestMapping(value="/user/{id:\\d+}",method=RequestMethod.GET)//如果希望对传递进来的参数作一些限制,使用正则表达式
    @JsonView(User.UserDetailView.class)
    public User getInfo(@PathVariable String id) {
        User user = new User();
        user.setUsername("tom");
        return user;
    }
    

    使用@JsonView控制json输出内容

    1.场景:在以上两个方法中,查询集合和查询用户详细信息时,期望查询用户集合时不返回密码给前端,而在查询单个用户信息时才返回。

    2.使用步骤:
    ①使用接口来声明多个视图
    ②在值对象的get方法上指定视图
    ③在Controller方法上指定视图

    在user实体中操作:

    package com.hcx.web.dto;
    
    import java.util.Date;
    
    import javax.validation.constraints.Past;
    
    import org.hibernate.validator.constraints.NotBlank;
    
    import com.fasterxml.jackson.annotation.JsonView;
    import com.hcx.validator.MyConstraint;
    
    public class User {
    
        public interface UserSimpleView{};
        //有了该继承关系,在显示detail视图的时候同时会把simple视图的所有字段也显示出来
        public interface UserDetailView extends UserSimpleView{};
    
        @MyConstraint(message="这是一个测试")
        private String username;
    
        @NotBlank(message = "密码不能为空")
        private String password;
    
        private String id;
    
        @Past(message="生日必须是过去的时间")
        private Date birthday;
    
    
        @JsonView(UserSimpleView.class)
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        @JsonView(UserSimpleView.class)
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        @JsonView(UserSimpleView.class) //在简单视图上展示该字段
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @JsonView(UserDetailView.class)
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    在具体的方法中操作Controller:

    @GetMapping
    @JsonView(User.UserSimpleView.class)
    public List<User> query(@RequestParam(name="username",required=false,defaultValue="tom") String username){
        System.out.println(username);
        List<User> users = new ArrayList<>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }
    
    @RequestMapping(value="/user/{id:\\d+}",method=RequestMethod.GET)//如果希望对传递进来的参数作一些限制,就需要使用正则表达式
    @JsonView(User.UserDetailView.class)
    public User getInfo(@PathVariable String id) {
        User user = new User();
        user.setUsername("tom");
        return user;
    }
    

    单元测试:

    //查询
    @Test
    public void whenQuerySuccess() throws Exception {
        String result = mockMvc.perform(get("/user")
                .param("username", "jojo")
                .param("age", "18")
                .param("ageTo", "60")
                .param("xxx", "yyy")
               //.param("size", "15")
               //.param("sort", "age,desc")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.length()").value(3))
                .andReturn().getResponse().getContentAsString();//将服务器返回的json字符串当成变量返回
    
        System.out.println(result);//[{"username":null},{"username":null},{"username":null}]
    }
    
    
    //获取用户详情
    @Test
    public void whenGetInfoSuccess() throws Exception {
        String result = mockMvc.perform(get("/user/1")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.username").value("tom"))
                .andReturn().getResponse().getContentAsString();
    
        System.out.println(result); //{"username":"tom","password":null}
    
    }
    

    代码重构:

    1.@RequestMapping(value=”/user”,method=RequestMethod.GET)
    替换成:
    @GetMapping(“/user”)

    2.在每个url中都重复声明了/user,此时就可以提到类中声明

    @RestController
    @RequestMapping("/user")//在类上声明了/user,在方法中就可以省略了
    public class UserController {
    
        @GetMapping
        @JsonView(User.UserSimpleView.class)
        public List<User> query(@RequestParam(name="username",required=false,defaultValue="tom") String username){
            System.out.println(username);
            List<User> users = new ArrayList<>();
            users.add(new User());
            users.add(new User());
            users.add(new User());
            return users;
        }
    
        @GetMapping("/{id:\\d+}")
        @JsonView(User.UserDetailView.class)
        public User getInfo(@PathVariable String id) {
            User user = new User();
            user.setUsername("tom");
            return user;
        }
    }
    

    三、处理创建请求

    1.@RequestBody 映射请求体到java方法的参数

    单元测试:

    @Test
    public void whenCreateSuccess() throws Exception {
    
        Date date = new Date();
        System.out.println(date.getTime());//1524741370816
    
        String content = "{\"username\":\"tom\",\"password\":null,\"birthday\":"+date.getTime()+"}";
        String result = mockMvc.perform(post("/user").contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(content))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").value("1"))
                .andReturn().getResponse().getContentAsString();
        System.out.println(result);//{"username":"tom","password":null,"id":"1","birthday":1524741229875}
    }
    

    Controller:要使用@RequestBody才可以接收前端传递过来的参数

    @PostMapping
    public User create(@RequestBody User user) {
    
        System.out.println(user.getId()); //null
        System.out.println(user.getUsername()); //tom
        System.out.println(user.getPassword());//null
        user.setId("1");
        return user;
    }
    

    2.日期类型参数的处理

    对于日期的处理应该交给前端或app端,所以统一使用时间戳

    前端或app端拿到时间戳,由他们自己决定转换成什么格式,而不是由后端转好直接给前端。

    前端传递给后台直接传时间戳:

    @Test
    public void whenCreateSuccess() throws Exception {
    
        Date date = new Date();
        System.out.println(date.getTime());//1524741370816
    
        String content = "{\"username\":\"tom\",\"password\":null,\"birthday\":"+date.getTime()+"}";
        String result = mockMvc.perform(post("/user").contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(content))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").value("1"))
                .andReturn().getResponse().getContentAsString();
        System.out.println(result);//{"username":"tom","password":null,"id":"1","birthday":1524741229875}(后台返回的时间戳)
    }
    

    Controller:

    @PostMapping
    public User create(@RequestBody User user) {
    
        System.out.println(user.getId()); //null
        System.out.println(user.getUsername()); //tom
        System.out.println(user.getPassword());//null
    
        System.out.println(user.getBirthday());//Thu Apr 26 19:13:49 CST 2018(Date类型)
        user.setId("1");
        return user;
    }
    

    3.@Valid注解和BindingResult验证请求参数的合法性并处理校验结果

    1.hibernate.validator中的常用验证注解:

    注解及其含义.png

    ①在实体中添加相应验证注解:

    @NotBlank
    private String password;
    

    ②后台接收参数时加@Valid注解

    @PostMapping
    public User create(@Valid @RequestBody User user) {
    
        System.out.println(user.getId()); //null
        System.out.println(user.getUsername()); //tom
        System.out.println(user.getPassword());//null
    
        System.out.println(user.getBirthday());//Thu Apr 26 19:13:49 CST 2018
        user.setId("1");
        return user;
    }
    

    2.BindingResult:带着错误信息进入方法体

    @PostMapping
    public User create(@Valid @RequestBody User user,BindingResult errors) {
    
        if(errors.hasErrors()) {
            //有错误返回true
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
            //may not be empty
        }
    
        System.out.println(user.getId()); //null
        System.out.println(user.getUsername()); //tom
        System.out.println(user.getPassword());//null
    
        System.out.println(user.getBirthday());//Thu Apr 26 19:13:49 CST 2018
        user.setId("1");
        return user;
    }
    

    四、处理用户信息修改

    1.自定义消息

    @Test
    public void whenUpdateSuccess() throws Exception {
        //一年之后的时间
        Date date = new Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        System.out.println(date.getTime());//1524741370816
    
        String content = "{\"id\":\"1\",\"username\":\"tom\",\"password\":null,\"birthday\":"+date.getTime()+"}";
        String result = mockMvc.perform(put("/user/1").contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(content))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id").value("1"))
                .andReturn().getResponse().getContentAsString();
        System.out.println(result);//{"username":"tom","password":null,"id":"1","birthday":1524741229875}
    }
    

    Controller:

    @PutMapping("/{id:\\d+}")
    public User update(@Valid @RequestBody User user,BindingResult errors) {
    
        /*if(errors.hasErrors()) {
            //有错误返回true
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
            //may not be empty
        }*/
        if(errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> {
                //FieldError fieldError = (FieldError)error;
                //String message = fieldError.getField()+" "+error.getDefaultMessage();
                System.out.println(error.getDefaultMessage()); 
                //密码不能为空
                //生日必须是过去的时间
                //birthday must be in the past
                //password may not be empty
            }
            );
        }
        System.out.println(user.getId()); //null
        System.out.println(user.getUsername()); //tom
        System.out.println(user.getPassword());//null
    
        System.out.println(user.getBirthday());//Thu Apr 26 19:13:49 CST 2018
        user.setId("1");
        return user;
    }
    

    实体:

    public class User {
    
        public interface UserSimpleView{};
        //有了该继承关系,在显示detail视图的时候同时会把simple视图的所有字段也显示出来
        public interface UserDetailView extends UserSimpleView{};
    
        @MyConstraint(message="这是一个测试")
        private String username;
    
        @NotBlank(message = "密码不能为空")
        private String password;
    
        private String id;
    
        @Past(message="生日必须是过去的时间")
        private Date birthday;
    
        @JsonView(UserSimpleView.class)
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        @JsonView(UserSimpleView.class)
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        @JsonView(UserSimpleView.class) //在简单视图上展示该字段
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @JsonView(UserDetailView.class)
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
    }
    

    2.自定义校验注解

    创建一个注解MyConstraint:

    @Target({ElementType.METHOD,ElementType.FIELD})//可以标注在方法和字段上
    @Retention(RetentionPolicy.RUNTIME)//运行时注解
    @Constraint(validatedBy = MyConstraintValidator.class)//validatedBy :当前的注解需要使用什么类去校验,即校验逻辑
    public @interface MyConstraint {
    
        String message();//校验不通过要发送的信息
    
        Class<?>[] groups() default { };
    
        Class<? extends Payload>[] payload() default { };
    
    }
    

    校验类:MyConstraintValidator:

    public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Object> {
    
        /*ConstraintValidator<A, T>
        参数一:验证的注解
        参数二:验证的类型
        ConstraintValidator<MyConstraint, String> 当前注解只能放在String类型字段上才会起作用
        */
        @Autowired
        private HelloService helloService;
    
        @Override
        public void initialize(MyConstraint constraintAnnotation) {
            System.out.println("my validator init");
        }
    
        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            helloService.greeting("tom");
            System.out.println(value);
            return false;//false:校验失败;true:校验成功
        }
    
    }
    

    五、处理删除

    单元测试:

    @Test
    public void whenDeleteSuccess() throws Exception {
        mockMvc.perform(delete("/user/1")
            .contentType(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(status().isOk());
    }
    

    Controller:

    @DeleteMapping("/{id:\\d+}")
    public void delete(@PathVariable String id) {
        System.out.println(id);
    }
    

    六、RESTful API错误处理

    1.Spring Boot中默认的错误处理机制

    Spring Boot中默认的错误处理机制,
    对于浏览器是响应一个html错误页面,
    对于app是返回错误状态码和一段json字符串

    2.自定义异常处理

    ①针对浏览器发出的请求

    在src/mian/resources文件夹下创建文件夹error编写错误页面

    错误页面.png

    对应的错误状态码就会去到对应的页面

    只会对浏览器发出的请求有作用,对app发出的请求,错误返回仍然是错误码和json字符串

    ②针对客户端app发出的请求

    自定义异常:

    package com.hcx.exception;
    
    public class UserNotExistException extends RuntimeException{
    
        private static final long serialVersionUID = -6112780192479692859L;
    
        private String id;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public UserNotExistException(String id) {
            super("user not exist");
            this.id = id;
        }
    
    }
    

    在Controller中抛自己定义的异常

    //发生异常时,抛自己自定义的异常
    @GetMapping("/{id:\\d+}")
    @JsonView(User.UserDetailView.class)
    public User getInfo1(@PathVariable String id) {
        throw new UserNotExistException(id);
    }
    

    默认情况下,springboot不读取id的信息

    抛出异常时,进入该方法进行处理:
    ControllerExceptionHandler:

    @ControllerAdvice //只负责处理异常
    public class ControllerExceptionHandler {
    
        @ExceptionHandler(UserNotExistException.class)
        @ResponseBody
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        public Map<String, Object> handleUserNotExistException(UserNotExistException ex){
            Map<String, Object> result = new HashMap<>();
            //把需要的信息放到异常中
            result.put("id", ex.getId());
            result.put("message", ex.getMessage());
            return result;
        }
    
    }
    

    完整Demo链接:https://github.com/GitHongcx/RESTfulAPIDemo

    展开全文
  • 一、SpringBoot 框架的特点1、聊聊 Springboot2.0 特点1)SpringBoot继承了Spring优秀的基因,上手难度小2)简化配置,提供各种默认配置来简化项目配置3)内嵌式容器简化Web项目,简化编码Spring Boot 则会帮助开发着...

    一、SpringBoot 框架的特点

    1、聊聊 Springboot2.0 特点

    1)SpringBoot继承了Spring优秀的基因,上手难度小

    2)简化配置,提供各种默认配置来简化项目配置

    3)内嵌式容器简化Web项目,简化编码

    Spring Boot 则会帮助开发着快速启动一个 web 容器,在 Spring Boot 中,只需要在 pom 文件中添加如下一个 starter-web 依赖即可.

    org.springframework.boot spring-boot-starter-web

    4)发展趋势看

    微服务是未来发展的趋势,项目会从传统架构慢慢转向微服务架构,因为微服务可以使不同的团队专注于更小范围的工作职责、使用独立的技术、更安全更频繁地部署。

    2、一张图形容学SpringBoot的心情

    3381dab35a00abb057930c337130ffa2.gif

    二、搭建SpringBoot的环境

    1、创建一个简单的Maven项目

    a31aab5d58f89ec1108439241ca1b60e.png

    2、引入核心依赖

    org.springframework.boot spring-boot-starter-web

    3、编写配置文件

    application.yml

    # 端口server: port: 8001

    4、启动文件注解

    import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class,args) ; }}

    丝毫没有问题,就这样吧启动上面这个类,springboot的基础环境就搭建好了。

    想想之前的Spring框架的环境搭建,是不是就是这个感觉:意会一下吧。

    三、SpringBoot2.0 几个入门案例

    1、创建一个Web接口

    import com.boot.hello.entity.ProjectInfo;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * SpringBoot 2.0 第一个程序 */@RestControllerpublic class HelloController { @RequestMapping("/getInfo") public ProjectInfo getInfo (){ ProjectInfo info = new ProjectInfo() ; info.setTitle("SpringBoot 2.0 基础教程"); info.setDate("2019-06-05"); info.setAuthor("知了一笑"); return info ; }}

    @RestController 注解 等价 @Controller + @ResponseBody 返回Json格式数据。

    2、参数映射

    1)首先看看SpringBoot 如何区分环境

    0b0e9d15dc2b6a0171d7ec7014498790.png

    这里标识配置加载指定的配置文件。

    2)参数配置

    application-pro.yml

    user: author: 知了一笑 title: SpringBoot 2.0 程序开发 time: 2019-07-05

    3)参数内容读取

    @Componentpublic class ParamConfig { @Value("${user.author}") private String author ; @Value("${user.title}") private String title ; @Value("${user.time}") private String time ;// 省略 get 和 set 方法}

    4)调用方式

    /** * 环境配置,参数绑定 */@RestControllerpublic class ParamController { @Resource private ParamConfig paramConfig ; @RequestMapping("/getParam") public String getParam (){ return "["+paramConfig.getAuthor()+";"+ paramConfig.getTitle()+";"+ paramConfig.getTime()+"]" ; }}

    3、RestFul 风格接口和测试

    1)Rest风格接口

    /** * Rest 风格接口测试 */@RestController // 等价 @Controller + @ResponseBody 返回Json格式数据@RequestMapping("rest")public class RestApiController { private static final Logger LOG = LoggerFactory.getLogger(RestApiController.class) ; /** * 保存 */ @RequestMapping(value = "/insert
    展开全文
  • RESTful架构特点:(1)每一个URI代表一种资源;(2)客户端和服务器之间,传递这种资源的某种表现层;(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。具体介绍参考:一:没有 对象类型 的...

    首先补充一下什么是 Restful ,这里简单说一下,如果一个架构符合REST原则,就称它为RESTful架构。

    RESTful架构特点:

    (1)每一个URI代表一种资源;

    (2)客户端和服务器之间,传递这种资源的某种表现层;

    (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

    具体介绍参考:

    一:没有 对象类型 的多参数传递

    @POST

    @Path("/addFavor/")

    void addFavor(@QueryParam("linkId") String linkId, @QueryParam("userId") List userId,

    @QueryParam("favorTypeCode") String favorTypeCode, @QueryParam("linkTable") String linkTable);

    另一种方式可以通过 @PathParam 注解参数,这种方式要在 URL 地址后面声明 如:/{id},多参:/{id}{aaa}{bbb}

    @GET

    @Path("/{id}")

    @ApiMethod(path = "/api/rest/category/{id}", verb = ApiVerb.GET, description = "get category by id", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })

    @ApiResponseObject

    Category get(@ApiPathParam(name = "id", description = "The Category id") @PathParam("id") String id);

    二:包含 对象类型 的多参传递

    需要在对象前声明 @ApiBodyObject

    @POST

    @Path("/addFavor/")

    void addFavor(@QueryParam("linkId") String linkId, @ApiBodyObject User user,

    @QueryParam("favorTypeCode") String favorTypeCode, @QueryParam("linkTable") String linkTable);

    @ApiBodyObject 相当于 SpringMVC 的 @RequestBody

    参数注解的作用就是将 xml/json (具体那种看配置,cxf 是json) 转换为实体对象如 User 传递给实现方法,如下:

    @Override

    @Transactional(readOnly = false)

    public void addFavor(String linkId, User user, String favorTypeCode, String linkTable) {

    }

    三:多 对象参数 传递

    Restful 仅支持多个参数中,最多只能有一个是对象参数,就比如一个 Form 表单中只能提交一个对象

    解决办法:将多个对象参数封装到一个大对象中,比如新建一个 VO 把这些对象参数都放进去,或者放到Map,List 这些也行

    四:Jersey

    上面的代码基于 Jersey框架实现,下面来说说 Jersey与 RESTful的关系:

    开发 RESTful WebService 意味着支持在多种媒体类型以及抽象底层的客户端-服务器通信细节,如果没有一个好的工具包可用,这将是一个困难的任务

    为了简化使用Java开发 RESTful WebService 及其客户端,一个轻量级的标准被提出:JAX-RS API

    Jersey RESTful WebService框架是一个开源的、产品级别的JAVA框架,支持JAX-RS API并且是一个JAX-RS(JSR 311和 JSR 339)的参考实现

    Jersey不仅仅是一个JAX-RS的参考实现,Jersey提供自己的API,其API继承自JAX-RS,提供更多的特性和功能以进一步简化RESTful service和客户端的开发

    Reference:

    展开全文
  • 本文源码 GitHub:知了一笑 https://github.com/cicadasmile/spring-boot-base 一、SpringBoot 框架的特点 1、SpringBoot2.0 特点 1)SpringBoot继承了Spring优秀的基因,上手难度小 2)简化配置,提供各...
    本文源码
    GitHub:知了一笑
    https://github.com/cicadasmile/spring-boot-base
    

    一、SpringBoot 框架的特点

    1、SpringBoot2.0 特点

    1)SpringBoot继承了Spring优秀的基因,上手难度小

    2)简化配置,提供各种默认配置来简化项目配置

    3)内嵌式容器简化Web项目,简化编码

    Spring Boot 则会帮助开发着快速启动一个 web 容器,在 Spring Boot 中,只需要在 pom 文件中添加如下一个 starter-web 依赖即可.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

    4)发展趋势看 微服务是未来发展的趋势,项目会从传统架构慢慢转向微服务架构,因为微服务可以使不同的团队专注于更小范围的工作职责、使用独立的技术、更安全更频繁地部署。

    二、搭建SpringBoot的环境

    1、创建一个Maven项目

    2、引入核心依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

    3、编写配置文件

    application.yml

    # 端口
    server:
      port: 8001
    

    4、启动文件注解

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication
    public class HelloApplication {
        public static void main(String[] args) {
            SpringApplication.run(HelloApplication.class,args) ;
        }
    }
    

    丝毫没有问题,就这样吧启动上面这个类,springboot的基础环境就搭建好了。 想想之前的Spring框架的环境搭建,是不是就是这个感觉:意会一下吧。

    三、SpringBoot2.0 几个入门案例

    1、创建一个Web接口

    import com.boot.hello.entity.ProjectInfo;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    /**
     * SpringBoot 2.0 第一个程序
     */
    @RestController
    public class HelloController {
        @RequestMapping("/getInfo")
        public ProjectInfo getInfo (){
            ProjectInfo info = new ProjectInfo() ;
            info.setTitle("SpringBoot 2.0 基础教程");
            info.setDate("2019-06-05");
            info.setAuthor("知了一笑");
            return info ;
        }
    }
    

    @RestController 注解 等价 @Controller + @ResponseBody 返回Json格式数据。

    2、参数映射

    1)首先看看SpringBoot 如何区分环境

    这里标识配置加载指定的配置文件。

    2)参数配置 application-pro.yml

    user:
      author: 知了一笑
      title: SpringBoot 2.0 程序开发
      time: 2019-07-05
    

    3)参数内容读取

    @Component
    public class ParamConfig {
        @Value("${user.author}")
        private String author ;
        @Value("${user.title}")
        private String title ;
        @Value("${user.time}")
        private String time ;
    	// 省略 get 和 set 方法
    }
    

    4)调用方式

    /**
     * 环境配置,参数绑定
     */
    @RestController
    public class ParamController {
    
        @Resource
        private ParamConfig paramConfig ;
    
        @RequestMapping("/getParam")
        public String getParam (){
            return "["+paramConfig.getAuthor()+";"+
                    paramConfig.getTitle()+";"+
                    paramConfig.getTime()+"]" ;
        }
    }
    
    

    3、RestFul 风格接口和测试

    1)Rest风格接口

    /**
     * Rest 风格接口测试
     */
    @RestController // 等价 @Controller + @ResponseBody 返回Json格式数据
    @RequestMapping("rest")
    public class RestApiController {
        private static final Logger LOG = LoggerFactory.getLogger(RestApiController.class) ;
        /**
         * 保存
         */
        @RequestMapping(value = "/insert",method = RequestMethod.POST)
        public String insert (UserInfo userInfo){
            LOG.info("===>>"+userInfo);
            return "success" ;
        }
        /**
         * 查询
         */
        @RequestMapping(value = "/select/{id}",method = RequestMethod.GET)
        public String select (@PathVariable Integer id){
            LOG.info("===>>"+id);
            return "success" ;
        }
    }
    

    2)测试代码

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = MockServletContext.class)
    @WebAppConfiguration
    public class TestRestApi {
    
        private MockMvc mvc;
        @Before
        public void setUp() throws Exception {
            mvc = MockMvcBuilders.standaloneSetup(new RestApiController()).build();
        }
    
        /**
         * 测试保存接口
         */
        @Test
        public void testInsert () throws Exception {
            RequestBuilder request = null;
            request = post("/rest/insert/")
                    .param("id", "1")
                    .param("name", "测试大师")
                    .param("age", "20");
            mvc.perform(request)
                    .andExpect(content().string(equalTo("success")));
        }
    
        /**
         * 测试查询接口
         */
        @Test
        public void testSelect () throws Exception {
            RequestBuilder request = null;
            request = get("/rest/select/1");
            mvc.perform(request)
                    .andExpect(content().string(equalTo("success")));
        }
    }
    

    这样SpringBoot2.0的入门案例就结束了,简单,优雅,有格调。

    四、源代码

    GitHub:知了一笑
    https://github.com/cicadasmile/spring-boot-base
    码云:知了一笑
    https://gitee.com/cicadasmile/spring-boot-base
    

    转载于:https://my.oschina.net/cicadasmile/blog/3071380

    展开全文
  • 一、SpringBoot 框架的特点1、SpringBoot2.0 特点1)SpringBoot继承了Spring优秀的基因,上手难度小 2)简化配置,提供各种默认配置来简化项目配置 3)内嵌式容器简化Web项目,简化编码Spring Boot 则会帮助开发着...
  • restful风格

    2019-10-06 14:11:00
    1.什么是restful风格 restful不是一种新技术,而是一种编程风格,一种约定RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使...
  • restful是目前最流行之一的api接口设计风格,主要有以下特点 1、资源 2、统一的接口url 3、无状态 总的一句话,restful是一种接口设计风格,没有很固定的限制,只要满足条件,都算restful 它通过一个唯一并且统一的...
  • RESTful风格了解

    2020-06-17 17:22:08
    ​ 又一次工作中要求接口的形式需要按照RESTful风格,由于第一次听到这个名词,所以来了解一下。 ​ RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。 ​ 其实...
  • RESTful风格

    2019-09-25 16:24:58
    目录1 产生背景2 简介3 特点4 使用规定5 spring mvc中实现restfule风格接口5.1 四种动作5.2 参考例子6 restful的URL与传统URL对比 1 产生背景 网络应用程序,越来越流行前端和后端的分离设计。当前的发展趋势是前端...
  • RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。RESTFUL特点包括:1、每一个URI代表1种资源;2、客户端使用GET、POST、PUT、...
  • RESTful接口

    2020-06-01 15:46:37
    1.什么是RESTful REST是英文representational state transfer(表象性状态转变)或者表述性状态转移;...2.RESTFUL特点 1、每一个URI代表1种资源; 2、客户端使用GET、POST、PUT、DELETE4个表示操作方式
  • REST 是一种软件架构风格、设计风格,提供一组设计原则和约束条件,是目前较流行的 API 设计规范,用于 Web 数据接口的设计。利用 HTTP 协议通过 GET、POST、PUT、PATCH、DELETE操作具有URI标识的服务器资源,可扩展...
  • RESTFUL架构风格

    2020-10-27 21:44:25
    在移动互联网的大潮下,随着docker等技术的兴起,『微服务』的概念也越来越被大家接受并应用于实践,日益增多的web service逐渐统一于RESTful 架构...1.1 RESTful架构风格特点 1.1.1 资源 1.1.2 统一接口 1.1.3 URI
  • 1. RESTful风格 1.1 简介与特点 RESTful是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTful适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络...
  • ResTful风格特点: 资源 资源就是,网络上的一个实体,比如一段文本,一张图片,一首歌,一种服务。总之就是一个具体的实体。资源要通过某种载体反应其内容。例如:文本可以用txt格式表现,也可以用HTML格式,...
  • 理解前后端不分离和前后端分离两种开发模式的特点 了解web项目两种开发模式的优缺点 web项目开发的两种模式 在Web项目开发中,有两种开发模式: 前后端不分离 前后端分离 前后端不分离 特点:前端看到的效果都是由...
  • 进行后台开发的时候, 我们经常说, 我们的接口是Restful的风格, 那Restful到底是什么呢?Restful风格有哪些特点呢?REST又跟Restful有什么关系?这篇文章主要是记录Restful API风格及其相关的一些知识点.
  • restful接口设计

    2018-07-27 19:38:50
    1.RESTFUL: 是一种设计风格, 而不是一种标准, 诞生于2000年, Thomas Fielding 在论文&lt;&lt;架构风格与基于网络的软件架构设计&gt;&gt;提及到的. 指的是客户端和服务器的交互形式.在后台中体现...
  • 简介:  Restful就是一个资源定位及... Restful架构风格特点:  REST即Representational State Transfer的缩写,可译为"表现层状态转化”。REST最大的几个特点为:资源、统一接口、URI和无状态。 1....
  • Restful接口学习笔记

    2019-08-13 17:41:52
    Restful接口学习笔记 参考:https://cloud.tencent.com/developer/news/315397 复制些到自己博客,方便复习。 Restful是一种软件架构风格,提供了一组设计原则和约束。主要用于客户端和服务端交互的项目。 有以下几...
  • Restful编码风格

    2021-02-21 19:19:11
    RESTFUL适用于移动互联网厂商作为业务接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。 优点:它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用...
  • RESTful 架构风格概述

    2017-04-27 11:35:00
    Outline 1. RESTful架构风格 1.1 RESTful架构风格特点 1.1.1 资源 1.1.2 统一接口 1.1.3 URI 1.1.4 无状态 1.2 ROA、SOA...
  • Restful特点

    热门讨论 2017-06-30 17:01:56
    HTTP就是该框架风格的一个典型应用。一方面,随着云计算和移动计算的兴起,很多企业愿意在互联网上共享自己的数据另一方面,在企业中,...Rest最大的的几个特点为:资源、统一接口、URI和无状态 1、资源 所谓资
  • RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。RESTFUL特点包括:1、每一个URI代表1种资源;2、客户端使用GET、POST、PUT、...
  • uri和url的区别?什么是restful风格

    千次阅读 2018-06-30 10:18:41
    restful风格四个特点1.资源,大多数资源以json格式表示2.统一的接口,crud分别对应http的get,post,put,delete3.uri。每个uri对应一个特定的资源4.无状态。所有的资源搜可以采用uri去定位,而不与其他资源产生耦合...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 449
精华内容 179
热门标签
关键字:

restful风格接口特点