SpringBoot REST 火推04

来源:互联网 发布:linux signal 11 编辑:程序博客网 时间:2024/05/18 13:08

SpringBoot REST API服务

前后分离架构

前后分离,指的是将后台服务处理和前台界面进行拆分,后台服务开发者,只关注业务处理,然后将处理结果以JSON或XML通用格式返回。 前台界面开发者,关注与用户交互界面的开发,调用后台服务,获取后台的JSON或XML之后,解析将其显示到界面中。


REST API服务

后台服务,一般都是采用HTTP请求和响应模式调用。 前台界面应用可以采用Ajax、HTTP工具包模式发送请求、获取服务器返回JSON或XML结果,之后解析显示到HTML界面或Android界面、IOS界面等。

REST是一种规则,用于限定发送HTTP请求的规则。

  1. URL设计规则

    • 原有URL一般是按操作设计

    http://localhost:8888/dept/list.do
    http://localhost:8888/dept/load.do
    http://localhost:8888/dept/add.do
    http://localhost:8888/dept/delete.do
    http://localhost:8888/dept/update.do

    • REST规则是按资源设计

    http://localhost:8888/dept //部门资源 http://localhost:8888/dept/1 //id=1的部门资源

  2. 请求提交类型

    • 原有URL提交类型

    一般是GET(无中文、参数少)和POST(中文、参数多)

    • REST规则提交类型

    查询 : GET
    添加 : POST
    更新 : PUT
    删除 : DELETE

    http://localhost:8888/dept/1

    //GET表示查询id=1的dept信息,等价于load.do
    //DELETE表示删除id=1的dept信息,等价于delete.do
    //PUT表示更新id=1的dept信息,等价于update.do

    http://localhost:8888/dept

    //GET表示查询所有的dept信息,等价于list.do
    //POST表示添加dept信息,等价于add.do

  3. 请求参数提交

    • 原有URL提交类型

      load.do?id=xx (get提交)或post提交

    • REST提交类型

      /dept/xx (将参数放置在请求URL路径中)

      /dept?key=value (跟在URL后面使用key=value)

      POST提交参数

Spring Boot开发REST服务

  1. 搭建SpringBoot环境

    • 创建maven project
    • 在pom.xml添加jar包定义

      <project>  <modelVersion>4.0.0</modelVersion>  <groupId>cn.xdl</groupId>  <artifactId>dept_server</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>war</packaging>  <parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.4.7.RELEASE</version>    <relativePath/>  </parent>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <java.version>1.7</java.version>  </properties>  <dependencies>    <!-- bean扫描、自动配置、@bean定义 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter</artifactId>    </dependency>    <!-- jdbc\连接池 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-jdbc</artifactId>    </dependency>    <!-- springboot核心ioc -->    <dependency>      <groupId>org.mybatis.spring.boot</groupId>      <artifactId>mybatis-spring-boot-starter</artifactId>      <version>1.2.2</version>    </dependency>    <!-- mvc -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <!-- test -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <!-- 热部署 -->    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-devtools</artifactId>    </dependency></dependencies></project>

      提示:ojdbc6驱动包build-path引入.

    • 添加application.properties

      #serverserver.port=8888#datasourcespring.datasource.username=SCOTTspring.datasource.password=TIGERspring.datasource.url=jdbc:oracle:thin:@localhost:1521:XEspring.datasource.driver-class-name=oracle.jdbc.OracleDriver
    • 添加主启动类MyBootAppliation.java

      @SpringBootApplicationpublic class MyBootApplication {    public static void main(String[] args) {        SpringApplication.run(MyBootApplication.class, args);    }}
  2. 整合Mybatis实现DeptDao

    • 编写实体类

      public class Dept implements Serializable{    private Integer deptno;    private String dname;    private String loc;    public Integer getDeptno() {        return deptno;    }    public void setDeptno(Integer deptno) {        this.deptno = deptno;    }    //... ... }
    • 编写Mapper接口

      public interface DeptDao {    @Select("select * from dept")    public List<Dept> findAll();    @Select("select * from dept where deptno=#{id}")    public Dept findById(int id);    @Delete("delete from dept where deptno=#{id}")    public int delete(int id);    @Update("update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}")    public int update(Dept dept);    @Update("update dept set dname=#{dname} where deptno=#{deptno}")    public int updateName(@Param("deptno")int id,@Param("dname")String name);    @Insert("insert into dept (deptno,dname,loc) values (#{deptno},#{dname},#{loc})")    @SelectKey(before=true,statement="select dept_seq.nextval from dual",            resultType=Integer.class,keyProperty="deptno")    public int save(Dept dept);}
    • 在主启动类添加@MapperScan注解

      @SpringBootApplication@MapperScan(basePackages={"cn.xdl.boot.dao"})public class MyBootApplication {    public static void main(String[] args) {        SpringApplication.run(MyBootApplication.class, args);    }}
  3. 基于mvc编写DeptController

    @RestControllerpublic class DeptController {    @Autowired    private DeptDao deptDao;    @RequestMapping(value="/dept",method=RequestMethod.GET)    public List<Dept> loadAll(){        return deptDao.findAll();    }    @RequestMapping(value="/dept",method=RequestMethod.POST)    public int add(Dept dept){         return deptDao.save(dept);    }    @RequestMapping(value="/dept/{id}",method=RequestMethod.GET)    public Dept load(@PathVariable("id")int id){        return deptDao.findById(id);    }    @RequestMapping(value="/dept/{id}",method=RequestMethod.DELETE)    public int delete(@PathVariable("id")int id){        return deptDao.delete(id);    }    @RequestMapping(value="/dept/{id}",method=RequestMethod.PUT)    public int update(Dept dept){        return deptDao.update(dept);    }}
  4. 测试REST服务

    • 浏览器输入http://localhost:8888/dept,测试/dept查询所有的部门信息

      [{"deptno":10,"dname":"JAVA","loc":null},{"deptno":20,"dname":"RESEARCH","loc":"DALLAS"},{"deptno":30,"dname":"SALES","loc":"CHICAGO"},{"deptno":40,"dname":"OPERATIONS","loc":"BOSTON"}]
    • 浏览器输入http://localhost:8888/dept/10,测试查询id=10的部门信息

      {"deptno":10,"dname":"JAVA","loc":null}

前台界面与后台服务交互

  1. 使用Ajax技术交互

    <!DOCTYPE html><html>    <head>    <meta charset="UTF-8">    <title>Insert title here</title>    <script type="text/javascript" src="js/jquery.min.js"></script>    <script type="text/javascript">    $(function(){        //发送ajax请求加载部门列表        $.ajax({            url:"http://localhost:8888/dept",            type:"get",            dataType:"json",            success:function(result){                //result就是服务器返回的json数据                for(var i=0;i<result.length;i++){                    var dept = result[i];                    var deptno = dept.deptno;                    var dname = dept.dname;                    var loc = dept.loc;                    //拼一个tr元素                    var str = "<tr><td>"+deptno+"</td><td>"+dname+"</td><td>"+loc+"</td></tr>";                    //将tr元素添加到table                    $("#dept_table").append(str);                }            },            error:function(){                alert("数据加载失败");            }        });    });    </script>    </head>    <body>        <h1>部门管理</h1>        <table id="dept_table">        </table>    </body></html>
  2. 域名不同,Ajax会存在跨域问题

    localhost:9999不允许访问localhost:8888,域名不同,json结果被限制返回。解决方法如下:

    • 在后台server端编写一个拦截器或过滤器

    拦截器示例:

    public class AjaxDomainInterceptor implements HandlerInterceptor{    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        //设置允许跨域响应的参数        response.setHeader("Access-Control-Allow-Origin", "*");        response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT");        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,            ModelAndView modelAndView) throws Exception {        // TODO Auto-generated method stub    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)            throws Exception {        // TODO Auto-generated method stub    }}
    • 配置拦截器或过滤器

    配置拦截器示例:

    @Configuration//拦截器配置,配置AjaxDomainInterceptor拦截器public class InterceptorConfig extends WebMvcConfigurerAdapter{    @Override    public void addInterceptors(InterceptorRegistry registry) {        AjaxDomainInterceptor ajaxDomain = new AjaxDomainInterceptor();        registry.addInterceptor(ajaxDomain).addPathPatterns("/**");//拦截所有请求    }}
原创粉丝点击