spring boot restful + react antd

作者: bd6b5cde5ce9 | 来源:发表于2018-06-05 17:57 被阅读317次

    这阵子由于任务要求,使用了spring boot 搭建restful api服务,前端用了tb的antd pro 框架
    记录一下其中的几个容易忘的知识点,想到了就记下来 随时补充,主要是为了以后自己随时翻阅的。各位看官看着不痛快就忍忍撒。

    关于后端

    1、maven 项目中的pom.xml,如果下载的时候不痛快
    可以在里面加入阿里的仓库

      <repositories>
        <repository>
          <id>spring-releases</id>
          <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
          <id>alimaven</id>
          <name>aliyun maven</name>
          <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </repository>
      </repositories>
    

    2、数据库连接
    pom.xml中加入依赖,一是写系统路径,而是mvn安装,下面是第一种

    <dependency>
          <groupId>com.oracle</groupId>
          <artifactId>ojdbc6</artifactId>
          <version>11.2.0.1</version>
          <scope>system</scope>
          <systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
        </dependency>
    

    application.properties中

    spring.datasource.driver-class-name=oracle.jdbc.OracleDriver //驱动名
    spring.datasource.url=jdbc:oracle:thin:@'//ip/数据库名' //格式
    spring.datasource.username=用户名
    spring.datasource.password=密码
    spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect//语言 11g可用这个
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update//是否自动更新
    spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.DefaultNamingStrategy//默认命名策略
    spring.jmx.enabled=false //禁止jmx
    

    3、打包

    <packaging>war</packaging>
    ....
    ....
      <build>
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    

    intellij idea 中的方法 在右侧边栏tab
    打开maven projects
    lifecycle - 双击package
    在target文件夹中即可找到打包生成的war文件

    4、先设计表再生成实体
    也可以反过来,都可以的
    先表后实体,则利用了Intellij idea 中的persistence这个功能,一般在左侧边栏就有这个tab

    5、常用的实体注解表示

        @Id
        @Column(name = "USERID", nullable = false, precision = 0)
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "userinfseq")
        @SequenceGenerator(name = "userinfseq", sequenceName =   "SEQ_USERINFID",allocationSize = 1)
        @Basic
        @Column(name = "USERNAME", nullable = true, length = 20)
        @ManyToOne(optional = true, fetch=FetchType.LAZY)
        @JoinColumn(name="ELEMENTS_BELONG_UNIT_ID", nullable = false)
        @OneToMany(mappedBy = "sUnitClassEntity",fetch=FetchType.LAZY,cascade = {CascadeType.PERSIST})
        @JsonBackReference //*****json very important 序列化忽略
        @JsonManagedReference //****反序列化不忽略 一般和@JsonBackReference配对使用
        @JsonIgnore //****均忽略
    

    6、api中常用注解

    @CrossOrigin
    @RestController
    @RequestMapping("/api/download")
    @RequestBody FileParams fileParams
    @Autowired
    @Transactional
    

    附上一个根据文件名下载的api 配合前端iframe 可实现无刷新下载

    @RequestMapping(method = RequestMethod.GET)
        public ResponseEntity<byte[]> download(
                @RequestParam(value="filename",required = true,defaultValue="") String filename
        ) throws IOException {
            File file = new File(this.getClass().getResource("/").getPath()+"data/"+filename);
            byte[] body = null;
            InputStream is = new FileInputStream(file);
            body = new byte[is.available()];
            is.read(body);
            HttpHeaders headers = new HttpHeaders();
            int statusCode = HttpStatus.SC_OK;
            headers.add("Content-Disposition", "attchement;filename=" + file.getName());
    
            return ResponseEntity.ok().headers(headers).body(body);
        }
    

    7、关于jpa数据操作
    每个controller里都有这段

        private JpaScoreRepository jpaScoreRepository;
    
        @Autowired
        public ReportDownLoadApiController(JpaScoreRepository jpaScoreRepository){
    
            this.jpaScoreRepository = jpaScoreRepository;
    
        }
    

    jpa的基本增删改可上官网阅读,来个函数感受下。

      public interface JpaProjectAccordingRepository extends JpaRepository<ProjectscoreRefEntity,Integer> {
        Page<ProjectscoreRefEntity> findPProjectscoreRefEntitiesByProjectscoreRefNameContaining(String projectname, Pageable pageable);
    }
    

    判断是否存在 新加的

      boolean existsByProjectname(String projectname);
    

    自定义原生sql使用方法

        @Modifying
        @Query(value = "delete from B_PROJECTINF where PROJECTID=?1", nativeQuery = true)
        void deleteProjectinfEntityById( int id);
    

    配合EntityManager可以解决一切你要的
    先定一个接口,里面返回的类型都可以自定义,但不用生成到表里,常规的类就可以,有时候需要你加上初始化函数,Page这里我是自定义的 copy jpa

    public class Page<T> {
        private int current;
        private int pageSize;
        private Long total;
        private List<T> results;
    
        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }
    
        public int getPageSize() {
            return pageSize;
        }
    
        public void setCurrent(int current) {
            this.current = current;
        }
    
        public int getCurrent() {
            return current;
        }
    
        public List<T> getResults() {
            return results;
        }
    
        public void setResults(List<T> results) {
            this.results = results;
        }
    
        public long getTotal() {
            return total;
        }
    
        public void setTotal(long total) {
            this.total = total;
        }
    }
    public interface SunitClass {
        void saveSunitClass(SUnitClassEntity sUnitClassEntity);
        Page<ProjectScore> findProjectScoreBy(String projectname, int userid, int pass, int pagesize, int currentpage);
        Page<ProjectScoreSort> findProjectScoreSortBy(int pagesize, int currentpage);
        Page<ProjectScore> findMyProjectScoreBy(String projectname, int userid, int pass,int pagesize, int currentpage);
        List<ReportData> findProjectScoreByProjectname(String projectname);
    }
    

    实现它,注意这个命名 必须是对应repository后面加Impl 自定义的话需要相关设置

    public class JpaScoreRepositoryImpl implements SunitClass {
        @PersistenceContext
        private EntityManager em;
    
        @Override
        public void saveSunitClass(SUnitClassEntity sUnitClassEntity) {
            SUnitClassEntity sUnitClassEntity1 = new SUnitClassEntity();
            sUnitClassEntity1.setUnitName(sUnitClassEntity.getUnitName());
            sUnitClassEntity1.setUnitScore(sUnitClassEntity.getUnitScore());
            sUnitClassEntity1.setUnitBelongProId(sUnitClassEntity.getUnitBelongProId());
            sUnitClassEntity1.setUnitNote(sUnitClassEntity.getUnitNote());
            sUnitClassEntity1.setUnitWeights(sUnitClassEntity.getUnitWeights());
            sUnitClassEntity1.setUnitPerson(sUnitClassEntity.getUnitPerson());
            sUnitClassEntity1.setUnitOk(sUnitClassEntity.getUnitOk());
            em.persist(sUnitClassEntity1);
            for(SElementsUnitEntity seu:sUnitClassEntity.getsElementsUnitEntitySets()){
                SElementsUnitEntity sElementsUnitEntity = new SElementsUnitEntity(seu.getElementsName(),seu.getElementsScore(),sUnitClassEntity1);
                em.persist(sElementsUnitEntity);
                for(SSubelementsElementsEntity ssub:seu.getsSubelementsElementsEntities()){
                    SSubelementsElementsEntity sSubelementsElementsEntity = new SSubelementsElementsEntity(ssub.getSubelementsName(),ssub.getSubelementsScore(),sElementsUnitEntity);
                    sElementsUnitEntity.getsSubelementsElementsEntities().add(sSubelementsElementsEntity);
                }
                sUnitClassEntity1.getsElementsUnitEntitySets().add(sElementsUnitEntity);
    
            }
        }
        ..........
    

    Repository头部加入SunitClass,ok,可以使用了

    public interface JpaScoreRepository extends JpaRepository<SUnitClassEntity,Integer>,SunitClass {
    
        boolean existsByunitBelongProIdAndUnitName(int unitBelongProId,String UnitName );
    
        boolean existsByUnitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);
    
        void deleteByUnitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);
    
        List<SUnitClassEntity> findAllByunitBelongProIdAndUnitPerson(int unitBelongProId, int UnitPerson);
    
        List<SUnitClassEntity> findAllByunitBelongProId(int unitBelongProId);
    
    }
    

    Spring boot 是自动调用jackson进行序列号化的,了解了上面几个知识点,稍加研究即可生产一套完整的restful api

    关于前端

    antd不得不说封装的控件很漂亮。
    1、登录它的官网,照着下载个demo即可使用
    2、以用户信息为例基本流程
    首先进行common 文件夹下的menu route 配置 路由及菜单(自动注册了model)
    然后models文件夹下创建路由菜单所关联的model

    import { queryUser, removeUser, addUser } from '../services/api';
    //不用太困惑 这里就说antd中dva封装的方法 你可以用自己的redux
    export default {
      namespace: 'userinf',
    
      state: {
        data: {
          list: [],
          pagination: {},
        },
      },
    
      effects: { //异步调用 所有的均通过这调用
        *fetch({ payload }, { call, put }) {
          const response = yield call(queryUser, payload); //异步以同步的方式执行,reponse返回了才会进行下一步
          yield put({ //调用更新state
            type: 'save',
            payload: response,
          });
        },
        *add({ payload, callback }, { call, put }) {
          const response = yield call(addUser, payload);
          yield put({
            type: 'save',
            payload: response,
          });
          if (callback) callback(); //如果有回调 则进行回调
        },
        *remove({ payload, callback }, { call, put }) {
          const response = yield call(removeUser, payload);
          yield put({
            type: 'save',
            payload: response,
          });
          if (callback) callback();
        },
      },
    

    然后创建用户界面的组件routes文件夹下,比较重要的是一定要进行connect关联

    @connect(({ userinf, loading }) => ({
      userinf,
      loading: loading.models.userinf,
    }))
    @Form.create()
    export default class TableList extends PureComponent {
    componentDidMount() {
        const { dispatch } = this.props;
        dispatch({
          type: 'userinf/fetch',
        });
      }
    .............
    

    然后写services 下 api,request 是 antd封装好的fetch,也可以自己进行调用

    export async function getAccountLogin(params) {
      return request(url, {
        method: 'POST',
        body: params,
      });
    }
    fetch(url,{credentials: 'omit'})
              .then(response => response.json())
              .then((body) => {
                if(body.code=="0"){
                  const data = body.result.map(project => ({
                    text: `${project.PROJECTNAME}`,
                    value: `${project.PROJECTNAME}`,
                  }));       
                  this.setState({
                    result: data,
                  });
                }
              });
    

    然后获取返回的data,根据组件的api可以进行使用

      const { userinf: { data }, loading } = this.props;//这里利用了es6语法,react很多,可以学习一下 
    

    ok,我们可以写一个react 页面了

    部署

    安装tomcat和jdk就不记录了,需要的时候搜索一大堆。
    要点主要是几个路径变量的配置
    来个连接 https://www.linuxidc.com/Linux/2015-01/112030.htm 亲测有效
    在tomcat的logs文件夹下可以查看日志记录 #这个很重要# nano catalina.out
    数据库驱动要放到正确位置。
    把打包生成的war放到webapps下就可以了,再配置一下你的域名
    通过server.xml配置域名

         <Host name="你的域名"  appBase="webapps"
               unpackWARs="true" autoDeploy="true">
    
           <!-- SingleSignOn valve, share authentication between web applications
                Documentation at: /docs/config/valve.html -->
           <!--
           <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
           -->
    
           <!-- Access log processes all example.
                Documentation at: /docs/config/valve.html
                Note: The pattern used is equivalent to using pattern="common" -->
           <Context docBase="你的包名" path="/" reloadable="true" debug="0" privileged="true"/>
    

    antd 直接运行 npm run build 生成dist 部署到你的web应用服务器就可以了,纯js+html
    附上新鲜出炉的系统截图一张


    屏幕快照 2018-06-05 下午5.44.11.png

    相关文章

      网友评论

      • bd6b5cde5ce9:一起交流,共同进步,我也是才用这套东西 :smile:
        bd6b5cde5ce9:@Jetaime_33a1 在火车上
        bd6b5cde5ce9:@Jetaime_33a1 可以说出你的问题,我现在没空呀
        Jetaime_33a1:此时此刻又过了8天,能不能冒昧的请求您发个小demo。我实验了一些方法,没有成功。特别是那个地图的展示,也是我正需要的。:pray: :pray: :pray:
      • Jetaime_33a1:非常感谢您得分享,最近正被这东西搞得晕头转向。谢谢
        bd6b5cde5ce9:@Jetaime_33a1 :smile:

      本文标题:spring boot restful + react antd

      本文链接:https://www.haomeiwen.com/subject/zxhmsftx.html