Controller
@Controller
处理器可以直接返回页面,需要和其他得注解一起使用
@RequestMapping
不带数据返回页面
@Controller
public class ViewController {
@RequestMapping("home") // url: http://localhost:8080/home
public String view() {
// 在resources里面创建一个home.html页面
return "home.html";
}
}
如果想要省掉
.html
的后缀,可以在recources文件夹下
application.properties
中添加配置:
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
带数据返回页面
package com.springbootlearn.annotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ViewController {
public static final String PAGE = "home";
/**
* 不带数据直接返回页面
* */
@RequestMapping("/home") // url: http://localhost:8080/home
public String view() {
// 在resources里面创建一个home.html页面
return PAGE;
}
/**
* 带数据直接返回页面,以ModelAndView的形式
* */
@RequestMapping("/data")
public ModelAndView data() {
ModelAndView view = new ModelAndView(PAGE);
view.addObject("str1", "hello");
view.addObject("str2", "world");
return view;
}
}
这里需要安装一些依赖,并更改配置。
<!-- html 模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
application.properties
下:
#freemarker
spring.freemarker.suffix=.html
spring.freemarker.template-loader-path=classpath:/static/
@RequestParam
@Controller
public class ParamsController {
public static final String PAGE = "param";
/**
* 获取路由传递过来的params
*/
// http://localhost:8080/param?id=1902
@RequestMapping("/param")
public ModelAndView param(@RequestParam(value="id", required = false, defaultValue = "0") int id,
@RequestParam(value="type", required = false) String type){
// 若无参传递,默认为null || 添加defaultValue = ""
if(type!=null && type == "morning"){
// ...
}
ModelAndView view = new ModelAndView(PAGE);
view.addObject("id",id);
return view;
}
}
@PathVariable
替换
@RequestParam
的写法
@RequestMapping("/path/{id}/{type}")
public ModelAndView path(@PathVariable int id,
@PathVariable(required = false) String type){
ModelAndView view = new ModelAndView(PAGE);
view.addObject("id",id);
return view;
}
@RestController
@GetMapping
@RestController
@RequestMapping("rest")
public class RestfulController {
// http://localhost:8080/rest/get
@GetMapping("get")
public User get(){
User user = new User(1,"ryuko");
return user;
}
}
请求这个接口将会收到以下格式的数据:
{"id": 1, "name": "ryuko"}
@RestController
@RequestMapping("rest")
public class RestfulController {
// http://localhost:8080/rest
@GetMapping
public String get(){
return "get success";
}
// http://localhost:8080/rest?id=1902
@GetMapping("{id}")
public String getById(@PathVariable("id") int id){
return "getById success";
}
}
@PostMapping
@RequestBody
如果希望前端以对象的方式将数据传递给后端,后端以对象的方式接收
需要添加
@RequestBody
修饰
@PostMapping
public User addUser(@RequestBody User user){
return user;
}
@ResponseBody
@Controller + @ResponseBody 等同于 @RestController
@Controller返回的是页面
@RestController返回的是输出结果,可以和@RequestMapping、@GetMapping一起使用
@CrossOrigin
解决跨域
不过有更好的解决办法:过滤器
Service
@Service
@Autowired
一般写代码的时候,肯定不能将内容杂糅在Controller里面,具体的逻辑应该交到专门的逻辑处理部分进行,所以先将逻辑处理抽离出来:
package com.springbootlearn.annotation.impl;
import com.springbootlearn.annotation.service.UserService;
import org.springframework.web.bind.annotation.PathVariable;
public class UserServiceImpl implements UserService {
@Override
public User get() {
User user = new User(1, "ryuko");
return user;
}
@Override
public User getById(@PathVariable("id") int id) {
User user = new User(1, "ryuko");
return user;
}
}
此时,在Controller层中可以将逻辑处理部分摘除,并引入
UserServiceImpl
实体类:
package com.springbootlearn.annotation.controller;
import com.springbootlearn.annotation.impl.UserServiceImpl;
import com.springbootlearn.annotation.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("action")
public class ActionController {
private UserService userService;
@GetMapping
public User get(){
userService = new UserServiceImpl();
return userService.get();
}
@GetMapping("{id}")
public User getById(@PathVariable("id") int id){
userService = new UserServiceImpl();
return userService.getById(id);
}
}
注意看这里,进行了两次
new UserServiceImpl();
的操作,为了解决这个问题,回到
UserServiceImpl
类。
注意
:需要在实现类中设置@Service:
@Service
public class UserServiceImpl implements UserService {
// ...
}
然后在
ActionController
类中进行自动装配,获取到bean:
package com.springbootlearn.annotation.controller;
import com.springbootlearn.annotation.impl.UserServiceImpl;
import com.springbootlearn.annotation.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("action")
public class ActionController {
@Autowired
private UserService userService;
@GetMapping
public User get(){
return userService.get();
}
@GetMapping("{id}")
public User getById(@PathVariable("id") int id){
return userService.getById(id);
}
}
@Component
和Service类似,不过它的用处更广,Service是用来处理逻辑的,Component既可以用来处理逻辑,也可以在Controller中被调用。
@Resource
如果接口实现只有一个,那么用@Autowired就可以了,也不需要指定名字。
如果接口有多个实现,那么,用@Resource,并指定name(建议)
或者使用@Autowired+@Qualifier+Qualifier的value值
现在有两个类,都继承自
UserService
接口:
@Service
public class UserServiceImpl implements UserService {
// ...
}
@Service
public class AdminServiceImpl implements UserService {
// ...
}
那么,在
UserActionController
类中,采用Autowired自动装配的方式将会报错,在编译的时候,无法判断这里的对象在后期,具体要用哪个子类的方法:
@Autowired
private UserService userService;
所以需要采用@Resource方法表明:
// 这里的 a 需要小写
@Recource(name = "adminServiceImpl")
private UserService adminService;
如果后期需要在
UserActionController
类中采用
UserService
的两个子类,可以这样定义:
@Recource(name = "adminServiceImpl")
private UserService adminService;
@Recource(name = "userServiceImpl")
private UserService userService;
@Qualifier
@Recource == @Qualifier + @Autowired
@Recource(name = "adminServiceImpl")
private UserService adminService;
// 等价
@Autowired
@Qualifier ("adminServiceImpl")
private UserService adminService;
@Configuration
@Configuration
public class MyBeans {
@Bean
public UserService adminServiceImpl() {
return new AdminServiceImpl();
}
// 也可以更换bean的名字
@Bean
public UserService admin() {
return new AdminServiceImpl();
}
// 也可以手动声明bean的名字
@Bean(name = 'adminServiceImpl')
public UserService admin() {
return new AdminServiceImpl();
}
@Bean
public UserService userServiceImpl() {
return new UserServiceImpl();
)
)
在自定义bean以后,自动装配依据这里的代码来进行:
@Autowired
@Qualifier ("admin")
private UserService adminService;
Value
@Value
在properties配置文件中添加如下配置:
local.username=ryuko
local.password=123456
然后在逻辑代码中使用配置中的变量:
@Value("${local.username}")
private String username;
@Value("${local.password}")
private String password;
// 在具体方法中使用这些值
@GetMapping("val")
public String getValue(){
System.out.println("passwprd = " + password);
}