spring boot+mybatis搭建一个后端restfull服务的实例详解

1、创建一个maven项目。

2、在pom.xml中引入依赖包,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.best</groupId>
 <artifactId>spring-boot-mybatis</artifactId>
 <version>1.0-SNAPSHOT</version>

 <properties>
  <java.version>1.8</java.version>
  <fastjson.version>1.2.74</fastjson.version>
  <spring.version>5.3.5.RELEASE</spring.version>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 </properties>
 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.5.RELEASE</version>
 </parent>
 <dependencies>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <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-starter-jdbc</artifactId>
   <exclusions>
    <!-- 排除 tomcat-jdbc 以使用 HikariCP -->
    <exclusion>
     <groupId>org.apache.tomcat</groupId>
     <artifactId>tomcat-jdbc</artifactId>
    </exclusion>
   </exclusions>
  </dependency>
  <!--  <dependency>-->
  <!--   <groupId>org.springframework.boot</groupId>-->
  <!--   <artifactId>spring-boot-starter-security</artifactId>-->
  <!--  </dependency>-->
  <dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.3</version>
  </dependency>
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.22</version>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.2.1</version>
  </dependency>
  <dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>${fastjson.version}</version>
  </dependency>
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.10</version>
  </dependency>
  <dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.3</version>
  </dependency>
 </dependencies>
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
     <source>1.8</source>
     <target>1.8</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
</project>

3、在使用mybatis之前,那么首先需要创建数据表,如:

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
 `create_date` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'user1', '2020-11-10 21:01:54');
INSERT INTO `user` VALUES ('2', 'user2', '2020-11-01 21:02:12');

4、然后配置数据库连接池,这里使用的是alibaba的druid,首先在resources中新建一个application.yml文件,内容如下:

spring:
 datasource:
 type: com.alibaba.druid.pool.DruidDataSource
 driver-class-name: com.mysql.cj.jdbc.Driver
 platform: mysql
 url: jdbc:mysql://localhost:3306/springboottest?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT
 username: root
 password:
server:
 port: 8080

5、然后新建一个包com.best.db,并新建一个DruidDBConfig类,代码如下:

package com.best.db;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * @author:sunxj
 * @date:2020-11-10 21:08:53
 * @description: 数据连接池
 */
@Configuration
public class DruidDBConfig {
 @Value("${spring.datasource.url}")
 private String url;
 @Value("${spring.datasource.username}")
 private String username;
 @Value("${spring.datasource.password}")
 private String password;
 @Value("${spring.datasource.driver-class-name}")
 private String driverClassName;
 @Bean//DataSource 对象为 Spring 容器所管理;
 @Primary//表示这里定义的DataSource将覆盖其他来源的DataSource。
 public DataSource dataSource(){
  DruidDataSource datasource = new DruidDataSource();
  datasource.setUrl(this.url);
  datasource.setUsername(username);
  datasource.setPassword(password);
  datasource.setDriverClassName(driverClassName);
  return datasource;
 }
 //配置数据库事务
 @Bean(name = "transactionManager")
 public DataSourceTransactionManager dbOneTransactionManager(
   @Qualifier("dataSource") DataSource dataSource) {
  return new DataSourceTransactionManager(dataSource);
 }
 //配置数据库工厂
 @Bean(name = "sqlSessionFactory")
 @ConditionalOnMissingBean(name = "sqlSessionFactory")
 public SqlSessionFactory dbOneSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
  final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  sessionFactory.setDataSource(dataSource);
  return sessionFactory.getObject();
 }
}

6、配置好连接池,那么就可以开始配置entity了,也就是与表映射的实体类,这里我们使用lombok的注解自动生成set和get方法,那么新建一个com.best.entity包,并新建一个User类,如:

package com.best.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

/**
 * @author:sunxj
 * @date:2020-11-10 21:12:58
 * @description:用户实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
 private Integer id;
 private String name;
 private Date createDate;
}

7、实体类创建好了之后,那么就是创建mybatis映射文件以及类了,这里的映射接口文件和Mapper.xml文件放到一起,首先创建一个com.best.dbo包,映射接口文件和.xml都放到这个包中,并创建一个接口UserMapper,如:

package com.best.dao;

import com.best.entity.User;
import org.springframework.stereotype.Repository;

import java.util.List;
/**
 * @author:sunxj
 * @date:2020-11-10 21:17:27
 * @description:用户表的映射接口文件
 */
@Repository
public interface UserMapper {
 List<User> selectAll();
 User selectById(Integer id);
}

8、配置Mapper映射的xml文件,文件名为UserMapper.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.best.dao.UserMapper">
 <resultMap type="com.best.entity.User" id="UserMap">
  <result property="id" column="id" jdbcType="INTEGER"></result>
  <result property="name" column="name" jdbcType="VARCHAR"></result>
  <result property="createDate" column="create_date" jdbcType="TIMESTAMP"></result>
 </resultMap>
 <select id="selectAll" resultMap="UserMap">
  SELECT * FROM user
 </select>
 <select id="selectById" resultMap="UserMap">
  SELECT * FROM user WHERE id=#{id}
 </select>
</mapper>

9、在配置好之后就可以在application.xml来指定mybatis扫描哪些映射文件,配置如下:

spring:
 datasource:
 type: com.alibaba.druid.pool.DruidDataSource
 driver-class-name: com.mysql.cj.jdbc.Driver
 platform: mysql
 url: jdbc:mysql://localhost:3306/springboottest?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT
 username: root
 password:
mybatis:
 #如果有多个目录则可以写多个,比如com/best/dao/*.xml,com/best/*/dao/*.xml,com/best/*/sss/*/dao/*.xml
 mapper-locations: classpath:com/best/dao/*.xml
 #配置包,这里同样可以配置多个,
 type-aliases-package: com.best.dao
server:
 port: 8080

10、配置好之后就开始配置service以及impl了,首先创建一个service和service/impl包,并在service下创建一个IUserService接口,并在impl下来实现该接口UserServiceImpl,代码如下:

package com.best.service;

import com.best.entity.User;
import java.util.List;
/**
 * @author:sunxj
 * @date:2020-11-10 21:33:23
 * @description:用户接口表
 */
public interface IUserService {
 List<User> selectAll();
 User selectById(Integer id);
}
package com.best.service.impl;

import com.best.dao.UserMapper;
import com.best.entity.User;
import com.best.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author:sunxj
 * @date:2020-11-10 21:34:34
 * @description:用户接口实现类
 */
@Service("userService")
public class UserServiceImpl implements IUserService {
 @Autowired
 private UserMapper userMapper;
 @Override
 public List<User> selectAll() {
  return userMapper.selectAll();
 }

 @Override
 public User selectById(Integer id) {
  return userMapper.selectById(id);
 }
}

11、在创建好service后,需要创建一个controller,如UserController,代码如下:

package com.best.controller;

import com.alibaba.fastjson.JSONObject;
import com.best.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author:sunxj
 * @date:2020-11-10 21:38:09
 * @description:
 */
@RestController//使用此注解,那么该类下的所有返回都是以json方式返回
@RequestMapping(value="best")//加上value后,在url访问时必须加上/best才行
public class UserController {
 @Autowired
 private IUserService userService;
 @RequestMapping("/getUser")
 public JSONObject getUser(HttpServletRequest request, HttpServletResponse response) {
  JSONObject obj = new JSONObject();
  obj.put("user","1111");
  return obj;
 }
}

12、创建好之后,最后创建一个spring-boot的入口文件,代码如下:

package com.best;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author:sunxj
 * @date:2020-11-10 21:46:43
 * @description:
 */
@SpringBootApplication
public class Application {
 public static void main(String[] args) {
  SpringApplication.run(Application.class,args);
 }
}

13、此时启动会提示无法找到com.best.dao.UserMapper,如:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-11-10 21:48:21.635 ERROR 10320 --- [   main] o.s.b.d.LoggingFailureAnalysisReporter : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field userMapper in com.best.service.impl.UserServiceImpl required a bean of type 'com.best.dao.UserMapper' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:

Consider defining a bean of type 'com.best.dao.UserMapper' in your configuration.

14、出现此问题是由于springboot在启动时,在UserServiceImpl中又使用到了UserMapper的自动注入,而springboot启动时就没有扫描到UserMapper,更不可能将它作为bean注入到IOC容器中,因此就无法注入了,那么需要再入口的main文件上加上@MapperScan即可,如:

package com.best;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author:sunxj
 * @date:2020-11-10 21:46:43
 * @description:
 */
@SpringBootApplication
@MapperScan({"com.best.dao"})//如果有多个可以使用{"com.best.dao","com.best.sss.dao"}
public class Application {
 public static void main(String[] args) {
  SpringApplication.run(Application.class,args);
 }
}

15、此时即可正常启动,如下图所示:

16、此时在浏览器中输入:http://localhost:8080/best/getUser即可,如下图所示:

17、以上只是搭建一个可以正常通过url访问,那么现在来访问数据库中的记录,在访问之前先创建一些封装类,比如将实体类封装成json、返回状态码等,先创建一个common包,在该包下创建entity、enums、utils等包,如下图所示:

18、然后在enums中创建一个ResultCode枚举类,此来定义了一些返回状态码信息,如下代码所示:

package com.best.common.enums;

/**
 * @author:sunxj
 * @date:2020-11-10 22:08:11
 * @description:返回码定义
 */
public enum ResultCode {
 //成功
 SUCCESS(200,"成功"),
 //默认失败
 COMMON_FAIL(404,"失败"),
 ;
 private Integer code;
 private String message;

 ResultCode(Integer code, String message) {
  this.code = code;
  this.message = message;
 }

 public Integer getCode() {
  return code;
 }

 public void setCode(Integer code) {
  this.code = code;
 }

 public String getMessage() {
  return message;
 }

 public void setMessage(String message) {
  this.message = message;
 }

 public static String getMessageByCode(Integer code) {
  for (ResultCode ele : values()) { //values会默认取出enum中的值对象列表,每个值都是一个ResultCode对象
   if (ele.getCode().equals(code)) {
    return ele.getMessage();
   }
  }
  return null;
 }
}

19、然后在entity中新建一个JsonResult类,用来封装统一返回的实体类,如:

package com.best.common.entity;

import com.best.common.enums.ResultCode;

import java.io.Serializable;

/**
 * @author:sunxj
 * @date:2020-11-10 22:06:50
 * @description:统一返回的实体类
 */
public class JsonResult<T> implements Serializable {
 private Boolean success;
 private Integer errorCode;
 private String errorMsg;
 private T data;

 public JsonResult() {
 }

 public JsonResult(Boolean success) {
  this.success = success;
  this.errorCode = success ? ResultCode.SUCCESS.getCode():ResultCode.COMMON_FAIL.getCode();
  this.errorMsg = success ? ResultCode.SUCCESS.getMessage():ResultCode.COMMON_FAIL.getMessage();
 }
 public JsonResult(Boolean success,ResultCode resultCode) {
  this.success = success;
  this.errorCode = success ? ResultCode.SUCCESS.getCode():(resultCode == null ? ResultCode.COMMON_FAIL.getCode():resultCode.getCode());
  this.errorMsg = success ? ResultCode.SUCCESS.getMessage():(resultCode == null ? ResultCode.COMMON_FAIL.getMessage():resultCode.getMessage());
 }
 public JsonResult(Boolean success,T data) {
  this.success = success;
  this.errorCode = success ? ResultCode.SUCCESS.getCode():ResultCode.COMMON_FAIL.getCode();
  this.errorMsg = success ? ResultCode.SUCCESS.getMessage() : ResultCode.COMMON_FAIL.getMessage();
  this.data = data;
 }
 public JsonResult(Boolean success,ResultCode resultCode,T data) {
  this.success = success;
  this.errorCode = success ? ResultCode.SUCCESS.getCode():(resultCode == null ? ResultCode.COMMON_FAIL.getCode():resultCode.getCode());
  this.errorMsg = success ? ResultCode.SUCCESS.getMessage():(resultCode == null ? ResultCode.COMMON_FAIL.getMessage():resultCode.getMessage());
  this.data = data;
 }

 public Boolean getSuccess() {
  return success;
 }

 public void setSuccess(Boolean success) {
  this.success = success;
 }

 public Integer getErrorCode() {
  return errorCode;
 }

 public void setErrorCode(Integer errorCode) {
  this.errorCode = errorCode;
 }

 public String getErrorMsg() {
  return errorMsg;
 }

 public void setErrorMsg(String errorMsg) {
  this.errorMsg = errorMsg;
 }

 public T getData() {
  return data;
 }

 public void setData(T data) {
  this.data = data;
 }
}

20、然后在utils中新建一个ResultTool,如下代码所示:

package com.best.common.utils;

import com.best.common.entity.JsonResult;
import com.best.common.enums.ResultCode;

/**
 * @author:sunxj
 * @date:2020-11-10 22:11:03
 * @description:json返回构造工具
 */
public class ResultTool {
 public static JsonResult success() {
  return new JsonResult(true);
 }
 public static <T> JsonResult<T> success(T data) {
  return new JsonResult<>(true,data);
 }
 public static JsonResult fail() {
  return new JsonResult(false);
 }
 public static JsonResult fail(ResultCode resultCode) {
  return new JsonResult(false,resultCode);
 }
}

21、创建好这些之后,那么就可以开始在controller中进行构造了,controller如下:

package com.best.controller;

import com.best.common.entity.JsonResult;
import com.best.common.utils.ResultTool;
import com.best.entity.User;
import com.best.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author:sunxj
 * @date:2020-11-10 21:38:09
 * @description:
 */
@RestController//使用此注解,那么该类下的所有返回都是以json方式返回
@RequestMapping(value="best")//加上value后,在url访问时必须加上/best才行
public class UserController {
 @Autowired
 private IUserService userService;
 @RequestMapping("/getUser")
 public JsonResult getUser(HttpServletRequest request, HttpServletResponse response) {
  List<User> users = userService.selectAll();
  return ResultTool.success(users);
 }
}

22、重新启动springboot,然后输入:http://localhost:8080/best/getUser,此时页面会出现如下错误:

23、后台显示如下错误:

package com.best.controller;

import com.best.common.entity.JsonResult;
import com.best.common.utils.ResultTool;
import com.best.entity.User;
import com.best.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author:sunxj
 * @date:2020-11-10 21:38:09
 * @description:
 */
@RestController//使用此注解,那么该类下的所有返回都是以json方式返回
@RequestMapping(value="best")//加上value后,在url访问时必须加上/best才行
public class UserController {
 @Autowired
 private IUserService userService;
 @RequestMapping("/getUser")
 public JsonResult getUser(HttpServletRequest request, HttpServletResponse response) {
  List<User> users = userService.selectAll();
  return ResultTool.success(users);
 }
}

23、这意思就是没有找到UserMapper接口文件中的selectAll方法,也就是没有和*Mapper.xml匹配成功,这是由于我们将.xml文件和java文件放在了java目录,而通过maven来管理,它不会将java文件中的xml文件打包进去的,因此需要再pom中的build中指定,如:

2020-11-10 22:15:10.487 ERROR 12992 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.best.dao.UserMapper.selectAll] with root cause
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.best.dao.UserMapper.selectAll
 at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235) ~[mybatis-3.5.5.jar:3.5.5]
 at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53) ~[mybatis-3.5.5.jar:3.5.5]
 at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:115) ~[mybatis-3.5.5.jar:3.5.5]
 at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_261]
 at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:102) ~[mybatis-3.5.5.jar:3.5.5]
 at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85) ~[mybatis-3.5.5.jar:3.5.5]
 at com.sun.proxy.$Proxy57.selectAll(Unknown Source) ~[na:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_261]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_261]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_261]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_261]
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at com.sun.proxy.$Proxy58.selectAll(Unknown Source) ~[na:na]
 at com.best.service.impl.UserServiceImpl.selectAll(UserServiceImpl.java:22) ~[classes/:na]
 at com.best.controller.UserController.getUser(UserController.java:26) ~[classes/:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_261]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_261]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_261]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_261]
 at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
 at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.10.RELEASE.jar:5.2.10.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:41002) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_261]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_261]
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.39.jar:9.0.39]
 at java.lang.Thread.run(Thread.java:748) [na:1.8.0_261]

24、然后在此重新运行,重新输入网址即可,如下图所示:

25、到此即可搭建完毕,使用此方法可以搭建一个前后端完全分离通过json通信的springboot后台。

到此这篇关于spring boot+mybatis搭建一个后端restfull服务的文章就介绍到这了,更多相关spring boot+mybatis搭建restfull服务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • spring boot2.0图片上传至本地或服务器并配置虚拟路径的方法

    最近写了关于图片上传至本地文件夹或服务器,上传路径到数据库,并在上传时预览图片.使用到的工具如下: 框架:spring boot 2.0 前端模板:thymeleaf 图片预览:js 首先,上传以及预览,js以及<input type="file">,以及预览图片的JS function Img(obj){ var imgFile = obj.files[0]; console.log(imgFile); var img = new Image(); var fr = ne

  • SpringBoot2.0 整合 Dubbo框架实现RPC服务远程调用方法

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层或模块,蓝色的表示与业务有交互,绿色的表示只对 Dubbo 内部交互. 2)图中背景方块 Consumer, Provider, Registry, Monitor 代表部署逻辑拓扑节点. 3)图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用. 4)图中只包含 RPC

  • 详解Springboot Oauth2 Server搭建Oauth2认证服务

    本教程源码 https://github.com/bestaone/HiAuth 源码比较全面,教程我就只介绍关键代码了,喜欢的点个star,谢谢! 关键词 微服务认证 Oauth2 认证中心 springboot spring-cloud-starter-oauth2 集成Oauth2 Oauth2 客户端 介绍 这里我将介绍两个部分 Oauth2 server 的开发 (hi-auth-web模块) Oauth2 client 的开发 (hi-mall-web模块) 效果图 himall.g

  • Spring Boot集成netty实现客户端服务端交互示例详解

    前言 Netty 是一个高性能的 NIO 网络框架,本文主要给大家介绍了关于SpringBoot集成netty实现客户端服务端交互的相关内容,下面来一起看看详细的介绍吧 看了好几天的netty实战,慢慢摸索,虽然还没有摸着很多门道,但今天还是把之前想加入到项目里的 一些想法实现了,算是有点信心了吧(讲真netty对初学者还真的不是很友好......) 首先,当然是在SpringBoot项目里添加netty的依赖了,注意不要用netty5的依赖,因为已经废弃了 <!--netty--> <

  • Springboot实现多服务器session共享

    本文实例为大家分享了springboot实现多服务器session共享的具体代码,供大家参考,具体内容如下 环境: springboot:2.0.4 redis:3.2.100 jdk:1.8 eclipse:4.9.0 1.原理 正常情况下,HTTPSession是通过servlet容器创建并管理的,创建成功后都保存在内存中,如果开发者需要对项目进行横向拓展搭建集群,那么可以用一些硬件和软件工具来做负载均衡,此时,来自同一用户的HTTP请求有可能会被发送到不同的实例上去,如何保证各个实例之间的

  • SpringBoot上传文件到本服务器 目录与jar包同级问题

    前言 看标题好像很简单的样子,但是针对使用jar包发布SpringBoot项目就不一样了. 当你使用tomcat发布项目的时候,上传文件存放会变得非常简单,因为你可以随意操作项目路径下的资源.但是当你使用SpringBoot的jar包发布项目的时候,你会发现,你不能像以前一样操作文件了.当你使用File file = new File()的时候根本不知道这个路径怎么办.而且总不能很小的项目也给它构建一个文件服务器吧.所以这次就来解决这样的问题. 不想知道细节的,可以直接跳转到最后封装的部分,里面

  • Spring Boot项目中jar包在服务器上启动的正确姿势

    关于 一般上来说,我们在服务器上启动一个jar,最简单的方式就是java -jar xx.jar,虽然这种方式简单但有时候我们的场景需要更多,例如常驻后台运行,在命令行窗口关闭的时候不中断项目,指定端口,并且输出日志到文件中等.所以这个时候我们通常会采用脚本启动和关闭项目,方便项目的统一管理. 脚本启动和关闭的案例 1.启动脚本 nohup java -jar ../webapp/xxx.jar --server.port=9002 >> ../logs/xxx.log & tail

  • spring boot+mybatis搭建一个后端restfull服务的实例详解

    1.创建一个maven项目. 2.在pom.xml中引入依赖包,如下所示: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="

  • Spring Boot 2 实战:自定义启动运行逻辑实例详解

    本文实例讲述了Spring Boot 2 实战:自定义启动运行逻辑.分享给大家供大家参考,具体如下: 1. 前言 不知道你有没有接到这种需求,项目启动后立马执行一些逻辑.比如缓存预热,或者上线后的广播之类等等.可能现在没有但是将来会有的.想想你可能的操作, 写个接口上线我调一次行吗?NO!NO!NO!这种初级菜鸟才干的事.今天告诉你个骚操作使得你的代码更加优雅,逼格更高. 2. CommandLineRunner 接口 package org.springframework.boot; impo

  • Spring Boot的filter(过滤器)简单使用实例详解

    过滤器(Filter)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public FilterRegistrationBean indexFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(new IndexFilter()); registration.addUrlPatterns("/&quo

  • Spring Boot 使用 SSE 方式向前端推送数据详解

    目录 前言 服务端 SSE工具类 在Controller层创建 SSEController.java 前端代码 前言 SSE简单的来说就是服务器主动向前端推送数据的一种技术,它是单向的,也就是说前端是不能向服务器发送数据的.SSE适用于消息推送,监控等只需要服务器推送数据的场景中,下面是使用Spring Boot 来实现一个简单的模拟向前端推动进度数据,前端页面接受后展示进度条. 服务端 在Spring Boot中使用时需要注意,最好使用Spring Web 提供的SseEmitter这个类来进

  • Spring加载properties文件的两种方式实例详解

    在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可,不需要修改源代码,这样更加方便.在Spring中也可以这么做,而且Spring有两种加载properties文件的方式:基于xml方式和基于注解方式.下面分别讨论下这两种方式. 1. 通过xml方式加载properties文件 我们以Spring实例化dataSource为例,我们一般会在beans

  • Spring 整合Shiro 并扩展使用EL表达式的实例详解

    Shiro是一个轻量级的权限控制框架,应用非常广泛.本文的重点是介绍Spring整合Shiro,并通过扩展使用Spring的EL表达式,使@RequiresRoles等支持动态的参数.对Shiro的介绍则不在本文的讨论范围之内,读者如果有对shiro不是很了解的,可以通过其官方网站了解相应的信息.infoq上也有一篇文章对shiro介绍比较全面的,也是官方推荐的,其地址是https://www.infoq.com/articles/apache-shiro. Shiro整合Spring 首先需要

  • springboot整合mybatis将sql打印到日志的实例详解

    在前台请求数据的时候,sql语句一直都是打印到控制台的,有一个想法就是想让它打印到日志里,该如何做呢? 见下面的mybatis配置文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-

  • Alfred + Gitee搭建免费图床的使用实例详解

    目录 环境 工具下载 思路 使用 依赖 实现 创建Gitee图床环境 配置Alfred workflow 复制剪切板中的图片到指定路径 git命令提交图片 图片压缩 拼接图片地址 环境 系统: Mac 工具: Alfred, git, homebrew, pngpaste. 语言: perl 其他: Gitee 工具下载 gitee.com/serpmelon/i… 思路 使用Gitee仓库作为图床, 使用Alfred工作流简化上传图片流程, 并将上传图片地址转换为markdown格式输出到剪切

  • Spring Boot整合ElasticSearch实现多版本兼容的方法详解

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和SpringBoot进行结合使用. ElasticSearch介绍 ElasticSearch是一个基于Lucene的搜索服务器,其实就是对Lucene进行封装,提供了 REST API 的操作接口 ElasticSearch作为一个高度可拓展的开源全文搜索和分析引擎,可用于快速地对大数据进行存储,搜索和分析.

  • spring boot 项目利用Jenkins实现自动化部署的教程详解

    本文主要讲解利用Jenkins实现spring boot项目的自动化部署: •1.后台技术架构:Spring boot 1.4.2.RELEASE +Mybatis 3+ Redis+ Mysql 5.6+JDK8; •2.代码构建工具:maven 3.3; •3.源代码托管工具:Gitlab; •4.利用maven的docker插件打包成docker镜像在docker容器中部署项目: •5.服务器是阿里云的ECS; 一.安装Jenkins 1.阿里云服务器安装Jenkins方式见如下链接地址

随机推荐