一般我们会分包进行创建,我这里简单创建了一个controller 的包,里面写相关的接口controller
然后再test包下我创建了一个Application 类,这个名词可以自己起。这个类是运行springboot的入口,需要进行配置下。
Application 代码如下:
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class,args);
}
}
@SpringBootApplication 注解:
@SpringBootApplication注解一般放在项目的一个启动类上,用来把启动类注入到容器中,用来定义容器扫描的范围,用来加载classpath环境中一些bean
@SpringBootApplication =@Configuration+@EnableAutoConfiguration+@ComponentScan
springboot 把这几个注解整合了。只需要写一个就可以
然后在main方法中添加SpringApplication.run(Application.class,args); 来启动应用程序
package com.test.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class TestController {
//测试用的集合
Map<String,Object> params=new HashMap<>();
/**
* 第一个接口测试
* @param name
* @return
*/
@RequestMapping("/test")
public Object getTest(String name){
params.clear();
params.put("name",name);
return params;
}
}
这里用到了两个注解,@RestController、 @RequestMapping
@RestController and @RequestMapping是springMVC的注解,不是springboot特有的
(1) @RestController
@RestController 是spring4 新加入的注解,相当于**@Controller +@ResponseBody** 两个注解的功能和
@Controller的作用表示该类是一个控制器,可以接受用户的输入并调用模型和视图去完成用户的需求。控制器本身不输出也不处理任何东西。 我们写的接口也就是控制器里面的方法。
@ResponseBody 表示 请求以json映射的方式返回。
所以@RestController注解的类就可以 接受请求——返回json
(2) @RequestMapping
这个注解可以加载类和方法上,我理解是表示资源的映射吧,为web请求指明路径。可以定义不同的映射规则
注解在方法上表示当前方法时一个web请求的处理方法,注解在类上,应该是常用的请求地址或路由啥的
上面方法中在@RequestMapping("/test") 方法中的"/test" 就是外部访问的接口地址,暂时我们没有指定请求方法
这样外部就能通过 http://localhost:8080/test?name=张三 来进行调用这个接口。
package com.test.controller;
import com.test.domain.User;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RestController
public class GetController {
Map<String, Object> params = new HashMap<>();
/**
* 从路径中取值
*
* @param cityID
* @param userID
* @return
*/
@RequestMapping(path = "/{city_id}/{user_id}")
public Object getUserID(@PathVariable("city_id") String cityID,
@PathVariable("user_id") String userID) {
params.clear();
params.put("cityID", cityID);
params.put("userID", userID);
return params;
}
/**
* 测试@GetMapping注解,以get方式请求接口
* @param id
* @param name
* @return
*/
@GetMapping(value = "/v1/getUser")
public Object getMappingTest(String id, String name) {
params.clear();
params.put("name", name);
params.put("id", id);
return params;
}
/**
* 测试,设置参数默认值,别名、以及是否必传参数
* @param id
* @param username
* @return
*/
@RequestMapping("/v1/getUser1")
public Object getMyappingTest1(@RequestParam(defaultValue = "888",name = "uid") String id, @RequestParam(required = true) String username){
params.clear();
params.put("username", username);
params.put("id", id);
return params;
}
/**
* 功能描述:bean对象传参
* 注意:1、注意需要指定http头为 content-type为application/json
* 2、使用body传输数据
* @param user
* @return
*/
@RequestMapping("/v1/save_user")
public Object saveUser(@RequestBody User user){
params.clear();
params.put("user", user);
return params;
}
/**
* 功能描述:测试获取http头信息
* @param accessToken
* @param id
* @return
*/
@GetMapping("/v1/get_header")
public Object getHeader(@RequestHeader("access_token") String accessToken, String id){
params.clear();
params.put("access_token", accessToken);
params.put("id", id);
return params;
}
/**
* 以HttpServletRequest获取所有请求数据
* @param request
* @return
*/
@GetMapping("/v1/test_request")
public Object testRequest(HttpServletRequest request){
params.clear();
String id = request.getParameter("id");
params.put("id",id);
return params;
}
@PostMapping("/v1/login")
public Object login(@RequestParam(required = true) String userName, @RequestParam(required = true)String passWrod){
params.clear();
params.put("name",userName);
params.put("pwd",passWrod);
return params;
}
@PostMapping("/v1/class")
public Object loginTest(User user){
params.clear();
params.put("name",user.getName);
params.put("pwd",user.getPassword);
return params;
}
@PutMapping("/v1/put")
public Object put(String id){
params.clear();
params.put("id", id);
return params;
}
@DeleteMapping("/v1/del")
public Object del(String id){
params.clear();
params.put("id", id);
return params;
}
}
注解简介: 1、单一参数@RequestMapping(path = "/{id}", method = RequestMethod.GET)
1) public String getUser(@PathVariable String id ) {}
2)@RequestMapping(path = "/{depid}/{userid}", method = RequestMethod.GET) 可以同时指定多个提交方法
getUser(@PathVariable("depid") String departmentID,@PathVariable("userid") String userid)
3)get、post、put、delete四种注解的封装
@GetMapping = @RequestMapping(method = RequestMethod.GET)
@PostMapping = @RequestMapping(method = RequestMethod.POST)
@PutMapping = @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)
4)@RequestParam(value = "name", required = true)
可以设置默认值,可以设置别名name="",可以设置是否必传 requeid=true或false
4)@RequestBody 请求体映射实体类,以json映射javaBean
需要指定http头为 content-type为application/json charset=utf-8
5)@RequestHeader 请求头,比如鉴权,可以获取请求头
@RequestHeader("access_token") String accessToken
6)HttpServletRequest request自动注入获取参数,可以拿到任何请求数据
详细区别
@RequestParam和@PathVariable
相同点与区别
@RequestParam和@PathVariable都能够完成类似的功能——因为本质上,它们都是用户的输入,只不过输入的部分不同,一个在URL路径部分,另一个在参数部分。要访问一篇博客文章,这两种URL设计都是可以的:
通过@PathVariable,例如/blogs/1
通过@RequestParam,例如blogs?blogId=1
那么究竟应该选择哪一种呢?建议:
1、当URL指向的是某一具体业务资源(或资源列表),例如博客,用户时,使用@PathVariable
2、当URL需要对资源或者资源列表进行过滤,筛选时,用@RequestParam
例如我们会这样设计URL:
/blogs/{blogId}
/blogs?state=publish而不是/blogs/state/publish来表示处于发布状态的博客文章
更多用法
一旦我们在方法中定义了@RequestParam变量,如果访问的URL中不带有相应的参数,就会抛出异常——这是显然的,Spring尝试帮我们进行绑定,然而没有成功。但有的时候,参数确实不一定永远都存在,这时我们可以通过定义required属性:
@RequestParam(value = “id”, required = false)
当然,在参数不存在的情况下,可能希望变量有一个默认值:
@RequestParam(value = “id”, required = false, defaultValue = “0”)
@Data : 注解在类上, 为类提供读写属性, 此外还提供了 equals()、hashCode()、toString() 方法
@Data
public class ActivityListParam{
private Integer id;
private Integer page;
private Integer count;
...
}
以往我的做法,还会通过快捷方法生成Getter,Setter,equals,hashCode,toString方法。但这个类里只声明了变量,没有各种方法,而在类名上加@Data注解,导入依赖:lombok.Data。在另一个类中导入该入参类后,通过activityListParam.是可以点出没有写的Get,Set等方法。因此,我理解为:@Data注解在类上时,简化java代码编写,为该类提供读写属性,还提供了equals(),hashCode(),toString()方法
@Getter/@Setter : 注解在类上, 为类提供读写属性
注意:@Configuration注解的配置类有如下要求:
@Configuration不可以是final类型;
@Configuration不可以是匿名类;
嵌套的configuration必须是静态类。
@Configuration 和 @Bean 注解
带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。
例子如下:
HelloWorld.java
package com.how2java.w3cschool.baseonjava;
public class HelloWorld {
private String message;
public void getMessage() {
System.out.println("Your message is:" + message);
}
public void setMessage(String message) {
this.message = message;
}
}
HelloWorldConfig.java
package com.how2java.w3cschool.baseonjava;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*
* 带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。
* @Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。
*/
@Configuration
public class HelloWorldConfig {
// 带有 @Bean 注解的方法名称作为 bean 的 ID,它创建并返回实际的 bean。也就是此时的bean
// id为helloWorld,你的配置类可以声明多个 @Bean。
// 一旦定义了配置类,你就可以使用 AnnotationConfigApplicationContext 来加载并把他们提供给 Spring 容器
@Bean
public HelloWorld helloWorld() {
return new HelloWorld();
}
}
MainApp.java
package com.how2java.w3cschool.baseonjava;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
}
如果在HelloWorldConfig.java中忘了@Bean的注解,将会遇到以下的错误
“No unique bean of type [com.how2java.w3cschool.baseonjava.HelloWorld] is defined: expected single bean but found 0: ”
从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@Configuation等价于
@Bean 等价于
@ComponentScan等价于
@Component 等价于
前言
@Configuration 用于定义配置类,可替换XML配置文件,被注解的类内部包含一个或多个@Bean注解方法。可以被AnnotationConfigApplicationContext或者AnnotationConfigWebApplicationContext 进行扫描。用于构建bean定义以及初始化Spring容器。
实例
@Configuration 加载Spring方法
Car.java
public class Car {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
定义Config类
@Configuration
public class Config {
public Config() {
System.out.println("TestConfig容器初始化...");
}
@Bean(name = "getMyCar")
public Car getCar() {
Car c = new Car();
c.setName("dankun");
return c;
}
}
实例化
public void testConfig() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Car car = (Car)context.getBean("car");
System.out.println(car.getName());
}
// 输出
// TestConfig容器初始化...
// dankun
@Configuration + @Component
@Configuration也附带了@Component的功能。所以理论上也可以使用@Autowared功能。上述代码可以改成下面形式
Car.java
@Component
public class Car {
@Value("dankun")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Config.java
@Configuration
@ComponentScan("com.wuyue.annotation")
public class Config {
public Config() {
System.out.println("TestConfig容器初始化...");
}
测试主入口
public class TestConfig {
@Test
public void testConfig() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Car car = (Car)context.getBean("car");
System.out.println(car.getName());
}
}
// 输出
// TestConfig容器初始化...
// dankun
总结
@Configuation等价于
@Bean 等价于
@ComponentScan等价于
@Component 等价于
@Bean VS @Component
两个注解的结果是相同的,bean都会被添加到Spring上下文中。
@Component 标注的是类,允许通过自动扫描发现。@Bean需要在配置类@Configuation中使用。
@Component类使用的方法或字段时不会使用CGLIB增强。而在@Configuration类中使用方法或字段时则使用CGLIB创造协作对象
假设我们需要将一些第三方的库组件装配到应用中或者 我们有一个在多个应用程序中共享的模块,它包含一些服务。并非所有应用都需要它们。
如果在这些服务类上使用@Component并在应用程序中使用组件扫描,我们最终可能会检测到超过必要的bean。导致应用程序无法启动
但是我们可以使用 @Bean来加载
因此,基本上,使用@Bean将第三方类添加到上下文中。和@Component,如果它只在你的单个应用程序中
@Api:用在请求的类上,表示对类的说明
tags=“说明该类的作用,可以在UI界面上看到的注解”
value=“该参数没什么意义,在UI界面上也看到,所以不需要配置”
@ApiOperation:用在请求的方法上,说明方法的用途、作用
value=“说明方法的用途、作用”
notes=“方法的备注说明”
@Controller
方法的返回值。默认是跳转路径。
如果想返回json对象,必须在方法的上面加@ResponseBody
@RestController
方法返回值,默认是json对象,也就是相当于@Controller里面的方法上添加了@ResponseBody如果方法返回值,需要跳转,那么方法的返回类型必须是View 或者ModelAndView.
一,@Controller
只是定义了一个控制器类,而使用 @RequestMapping 注解的方法才是处理请求的处理器。
@Controller
public class HospitalController {
//注入Service服务对象
@Autowired
private HospitalService hospitalService;
@RequestMapping(method = RequestMethod.POST, value = "/findAllHospital")
@ResponseBody
public Map findAllHospital(final HttpServletRequest request ,
@RequestBody Map parmMap , HttpServletResponse response){
Map map=parmMap ;//@RequestBody注解原因,系统会自动把request数据变成parmMap
........
........
return map;
}
}
用@Controller定义一个控制器类,
用@RequestMapping给出外界访问方法的路径,或者说触发路径 ,触发条件。
用@ResponseBody标记Controller类中的方法。把return的结果变成JSON对象返回。(如果没有这个注解,这个方法只能返回要跳转的路径即跳转的html/JSP页面。有这个注解,可以不跳转页面,只返回JSON数据)
二、@RestController注解
@RestController 也是Spring框架提供的注解。(Spring4.0之后新增的)
@RestController 注解相当于 @Controller + @ResponseBody 合在一起的作用。
Controller类中的方法返回值,默认是json对象,也就是相当于@Controller里面的方法上添加了@ResponseBody
如果方法返回值,需要跳转,那么方法的返回类型必须是View 或者ModelAndView.
@RestController
public class HospitalController {
//注入Service服务对象
@Autowired
private HospitalService hospitalService;
@RequestMapping(method = RequestMethod.POST, value = "/findAllHospital")
//方法上面可以不需要@ResponseBody注解,因为类上面用的是@RestController注解
public Map findAllHospital(final HttpServletRequest request ,
@RequestBody Map parmMap , HttpServletResponse response){
Map map=parmMap ;//@RequestBody注解原因,系统会自动把request数据变成parmMap
........
........
return map;
}
}
最常用的5个注解
@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiProperty:用对象接收参数时,描述对象的一个字段
其它若干
@ApiResponse:HTTP响应其中1个描述
@ApiResponses:HTTP响应整体描述
@ApiClass
@ApiError
@ApiErrors
@ApiParamImplicit
@ApiParamsImplicit
4.1、@Api修饰整个类,描述Controller的作用
4.2、@ApiOperation
用于描述一个方法或者接口
可以添加的参数形式:@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response = “接口返回参数类型”, notes = “接口发布说明”)
4.3、@ApiParam单个参数描述
@ApiParam(required = “是否必须参数”, name = “参数名称”, value = “参数具体描述”,dateType="变量类型”,paramType="请求方式”)
4.4、@ApiImplicitParam 一个请求参数
@ApiImplicitParam(required = “是否必须参数”, name = “参数名称”, value = “参数具体描述”,dateType="变量类型”,paramType="请求方式”)
@ApiOperation(value = "根据用户名获取用户的信息",notes = "查询数据库中的记录",httpMethod = "POST",response = String.class)
@ApiImplicitParam(name = "userName",value = "用户名",required = true,dataType = "String",paramType = "query")
4.5、@ApiImplicitParams 多个请求参数
参数和@ApiImplicitParam一致,只是这个注解可以添加多个参数而已
@ApiImplicitParams({
@ApiImplicitParam(name = "nickName",value = "用户的昵称",paramType = "query",dataType = "String",required = true),
@ApiImplicitParam(name = "id",value = "用户的ID",paramType = "query",dataType = "Integer",required = true)
})
public String getUserInfoByNickName(String nickName, Integer id) {
return "1234";
}
其余的都类似。
整个controller的代码如下
@RestController
@RequestMapping("/swagger")
@Api(value = "swagger2的demo例子")
public class SwaggerController {
@RequestMapping("/swagger")
@ResponseBody
@ApiOperation(value = "根据用户名获取用户的信息",notes = "查询数据库中的记录",httpMethod = "POST",response = String.class)
@ApiImplicitParam(name = "userName",value = "用户名",required = true,dataType = "String",paramType = "query")
public String getUserInfo(String userName) {
return "1234";
}
@RequestMapping(value = "/getuserinfobynickname",method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
@ApiOperation(value = "根据用户昵称获取用户信息",notes = "查询数据库中的记录")
@ApiImplicitParams({
@ApiImplicitParam(name = "nickName",value = "用户的昵称",paramType = "query",dataType = "String",required = true),
@ApiImplicitParam(name = "id",value = "用户的ID",paramType = "query",dataType = "Integer",required = true)
})
public String getUserInfoByNickName(String nickName, Integer id) {
return "1234";
}
@RequestMapping(value = "/getuserinfobyid",method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
@ApiOperation(value = "根据用户id获取用户信息",notes = "查询数据库中的记录",httpMethod = "POST")
public String getUserInfoById(@ApiParam(name = "nickName",value = "用户的昵称",required = true,defaultValue = "123-默认值")
String nickName,@ApiParam(name = "id",value = "用户ID",required = true) Integer id) {
return "1234";
}
@RequestMapping(value = "/userregister",method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
@ApiOperation(value = "register",notes = "注册的实体类")
public Register userRegister(Register register) {
return register;
}
}
对应的实体说明
@ApiModel(value = "用户注册的实体")
public class Register {
@ApiModelProperty(name = "userName",notes = "用户名",dataType = "String",required = true)
private String userName;
@ApiModelProperty(name = "nickName",notes = "用户昵称",dataType = "String",required = true)
private String nickName;
@ApiModelProperty(name = "age",notes = "用户年龄",dataType = "int",required = true)
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Register{" +
"userName='" + userName + '\'' +
", nickName='" + nickName + '\'' +
", age=" + age +
'}';
}
}
@EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置
1 @Controller
2 @RequestMapping("/")
3 public class HelloController {
4 @RequestMapping(value = "/helloWorld", method = RequestMethod.GET)
5 @ResponseBody
6 public String helloWorld() {
7 return"Hello World";
8 }
9 }
10
11 运行以上代码,在浏览器地址栏输入: http://localhost:8080/helloWorld
12 运行结果,页面上输出 Hello World
如果不加@responseBody注解,运行结果会怎样?
结果表明:如果在一个方法上使用了@RequestMapping注解,这时候,方法的返回值通常解析为跳转的路径, 也就是说,要跳转到指定的jsp页面。在这个代码实例中,要跳转到的是 Hello World.jsp 页面。 因为工程中尚未添加这个jsp文件,所以报出了 404 错误 (The requested resource is not available)。
如果添加了 @ResponseBody 这个注解, 则表明该方法的返回值直接写入到 HTTP Response Body 中。 这就是说,如果返回的是JSON, 就得必须添加 @ResponseBody 这个注解
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
之前用户使用的是3个注解注解他们的main类。分别是@Configuration,@EnableAutoConfiguration,@ComponentScan。由于这些注解一般都是一起使用,spring boot提供了一个统一的注解@SpringBootApplication。
@SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
@SpringBootApplication
public class ApplicationMain {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
分开解释@Configuration,@EnableAutoConfiguration,@ComponentScan。
1、@Configuration:提到@Configuration就要提到他的搭档@Bean。使用这两个注解就可以创建一个简单的spring配置类,可以用来替代相应的xml配置文件。
<beans>
<bean id = "car" class="com.test.Car">
<property name="wheel" ref = "wheel"></property>
</bean>
<bean id = "wheel" class="com.test.Wheel"></bean>
相当于:
@Configuration
public class Conf {
@Bean
public Car car() {
Car car = new Car();
car.setWheel(wheel());
return car;
}
@Bean
public Wheel wheel() {
return new Wheel();
}
}
@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。
2、@EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置。
3、@ComponentScan:会自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。