Spring实战(第四版)读书笔记15——接受请求的输入

Spring MVC允许多种方式将客户端中的数据传输到控制器的处理方法中,包括:

  • 查询参数
  • 表单参数
  • 路径变量

1、处理查询参数

控制器方法例子:

@RequestMapping(method=RequestMethod.GET)
	public List<Spittle> spittles(
			@RequestParam(value="max", defaultValue=MAX_LONG_AS_STRING) long max,
			@RequestParam(value="count", defaultValue="20") int count){
		return spittleRepository.findSpittles(max, count);
	}

注意,查询参数都是String类型的,因此defaultValue不能使用Long.MAX_VALUE。

测试方法例子:

@Test
	public void shouldShowPagedSpittles() throws Exception{
		List<Spittle> expectedSpittles = createSpittleList(50);
		SpittleRepository mockRepository = mock(SpittleRepository.class);
		when(mockRepository.findSpittles(238900, 50)).thenReturn(expectedSpittles);
		
		SpittleController controller = new SpittleController(mockRepository);
		MockMvc mockMvc = standaloneSetup(controller)
				.setSingleView(new InternalResourceView("/WEB-INF/views/spittles.jsp"))
				.build();
		
		mockMvc.perform(get("/spittle?max=238900&count=50"))
		.andExpect(view().name("spittles"))
		.andExpect(model().attributeExists("spittleList"))
		.andExpect(model().attribute("spittleList", 
				hasItems(expectedSpittles.toArray())));
	}

2、通过路径参数接受输入

控制器方法例子:

@RequestMapping(value="/{spittleId}", method=RequestMethod.GET)
	public String spittle(@PathVariable long spittleId, Model model) {
		model.addAttribute(spittleRepository.findOne(spittleId));
		return "spittle";
	}

测试方法例子:

@Test
	public void testSpittle() throws Exception{
		Spittle expectedSpittle = new Spittle("Hello", new Date());
		SpittleRepository mockRepository = mock(SpittleRepository.class);
		when(mockRepository.findOne(12345)).thenReturn(expectedSpittle);
		
		SpittleController controller = new SpittleController(mockRepository);
		MockMvc mockMvc = standaloneSetup(controller).build();
		
		mockMvc.perform(get("/spittles/12345"))
		.andExpect(view().name("spittle"))
		.andExpect(model().attributeExists("spittle"))
		.andExpect(model().attribute("spittle", expectedSpittle));
	}

3、处理表单

处理表单的控制器方法例子:

@RequestMapping(value="/{username}", method=RequestMethod.GET)
	public String showSpitterProfile(
			@PathVariable String username, Model model) {
		Spitter spitter = spitterRepository.findByUsername(username);
		model.addAttribute(spitter);
		return "profile";

测试处理表单的控制器方法例子:

@Test
	public void shouldProcessRegistration() throws Exception{
		SpitterRepository mockRepository = mock(SpitterRepository.class);
		Spitter unsaved = new Spitter("jbauer", "24hours", "Jack", "Bauer");
		Spitter saved = new Spitter(24L, "jbauer", "24hours", "Jack", "Bauer");
		when(mockRepository.save(unsaved)).thenReturn(saved);
		
		SpitterController controller = new SpitterController(mockRepository);
		MockMvc mockMvc = standaloneSetup(controller).build();
		
		mockMvc.perform(post("/spitter/register")
		.param("firstName", "Jack")
		.param("lastName", "Bauer")
		.param("username", "jbauer")
		.param("password", "24hours"))
		.andExpect(redirectedUrl("/spitter/jbauer"));
		
		verify(mockRepository, atLeastOnce()).save(unsaved);
	}

4、校验表单

java校验API所提供的校验注解(javax.validation.constraints):

在属性上添加校验注解例子:

@NotNull
@Size(min=5, max=16)
private String username;

在属性上添加校验注解并不能组织表单提交,因此必须在数据保存之前处理校验错误,例子如下:

	@RequestMapping(value="/register", method=RequestMethod.POST)
	public String processRegistration(@Valid Spitter spitter, Errors errors) {
		if(errors.hasErrors()) {
			return "registerForm";
		}
		
		spitterRepository.save(spitter);
		
		return "redirect:/spitter/" + spitter.getUsername();
	}

注:Errors参数要紧跟在带有@Valid注解的参数后面。

猜你喜欢

转载自blog.csdn.net/Nemoosi/article/details/107364266
今日推荐