一个简单的处理返回home页面的控制器:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller //声明为一个控制器
//@RequestMapping("/") 可以将映射处理放到类级别上,那么方法的映射就变成了对类级别的补充。
public class LoginController {
@RequestMapping(value="/home",method = RequestMethod.GET) //处理对''/home"的请求
public String home(){
return "home"; //返回视图名为home的视图
}
}
@Controller 基于@Component,因此会被spring组件扫描器 扫描到,并将其声明为spring上下文中的一个bean。
通过配置InternalResourceViewResolver,视图名home会被解析为 配置里的:
前缀+视图名+后缀的路径。
使用Junit编写测试类:
import org.junit.Assert;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
public class LoginControllerTest {
@Test
public void testHomePage() throws Exception{
LoginController loginController=new LoginController();
//只测试返回值的测试,并未发起get请求。
//Assert.assertEquals("home",loginController.home());
//使用mockMvc的方式
MockMvc mockMvc= MockMvcBuilders.standaloneSetup(loginController).build();
mockMvc.perform(get("/home")).andExpect(view().name("home"));
}
}
@RequestMapping中value接收多个映射的写法:
使用字符串数组传递:
value={"/home","/homepage"}
传递模型到视图中:
控制器方法带一个Model参数,通过model.addAttribute(key,value)来传递。
@RequestMapping(value="/users",method = RequestMethod.GET)
public String users(Model model){
model.addAttribute(key,vaule);
return "users";
}
Model是一个Map(Key-Value)集合。
如果不单独指定key,那么key的值会根据值的对象类型来推定。
java.util.Map 可以用来代替Model。
@RequestMapping(value="/users",method = RequestMethod.GET)
public String users(Map model){
model.put(key,value);
return "users";
}
直接返回对象: 并根据返回值推定视图名称。
@RequestMapping(value="/users",method = RequestMethod.GET)
public List<User> users(){
return userRepository.findUsers(Long.MAX_VALUE,20));
}
上面会执行:
- 将集合加入到value中。并推定key的值为value对象的类型,即userList。
- 再推定返回的视图名称。根据get请求来推定,因为本次请求是"/users",那么视图返回的结果就是return ''users"。
- 视图解析器根据InternalResourceViewResolver的设置,拼接出完整的视图名。
带参数的控制器方法
有时候控制器方法需要接受参数作为返回数据的查询条件,通过@RequestParam来声明。
@RequestMapping(value="/users",method = RequestMethod.GET)
public List<User> users(@RequestParam(value="name" defaultValue="peter") String name){
return userRepository.findUsersByName(name);
}
defaultValue 表示在没有指定value的值时,则使用默认值。
value值为显示在URL路径上的名称,如/users?name=peter。
面向资源的控制器请求:
通过在@RequestMapping中添加占位符来完成,占位符用{}括起来。
再通过@PathVariable("") 来使用路径变量。
@RequestMapping(value="/users/{userId}",method = RequestMethod.GET)
public List<User> users(@PathVariable("userId" ) String userId){
return userRepository.findOne(userId);
}
在请求路径中,不管占位符部分的值是什么,都会传递到方法参数userId中。
在本方法中,占位符的名称正好与参数名称一样。因此可以使用简写:
@RequestMapping(value="/users/{userId}",method = RequestMethod.GET)
public List<User> users(@PathVariable String userId){
return userRepository.findOne(userId);
}
也就是说:
如果@PathVariable中没有value属性的话,它会假设占位符的名称与方法的参数名相同。
即:
占位符是通过@PathVariable的value属性来查找方法参数名的,如果不设置@PathVariable的value属性,那么会将方法的参数名称作为value来查询。