java 带有模式的 Spring MockMvc redirectedUrl
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17834034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring MockMvc redirectedUrl with pattern
提问by Anil Bharadia
I have a simple PersonController
class that provides save()
method to persist the object from http post request.
我有一个简单的PersonController
类,它提供save()
了从 http post 请求中持久化对象的方法。
package org.rw.controller;
import java.sql.Timestamp;
import java.util.List;
import org.rw.entity.Person;
import org.rw.service.PersonService;
import org.rw.spring.propertyeditor.TimestampPropertyEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping(value="/person")
public class PersonController {
private static final Logger logger = LoggerFactory.getLogger(PersonController.class);
@Autowired
private PersonService personService;
@Autowired
TimestampPropertyEditor timestampPropertyEditor;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Timestamp.class, "dob", timestampPropertyEditor);
}
@RequestMapping(value="/save", method=RequestMethod.POST)
public String save(Model model, Person person) {
Long personId = personService.save(person);
return "redirect:view/" + personId;
}
}
As the save()
method returns as return "redirect:view/" + personId;
. It will be diffrerent for every request. it may be like "view/5"
or "view/6"
depending on the id of the object that has been persisted.
由于该save()
方法返回为return "redirect:view/" + personId;
. 每个请求都会有所不同。它可能类似于"view/5"
或"view/6"
取决于已持久化的对象的 id。
Then i have a simple class to test the above controller with spring mocking.
然后我有一个简单的类来使用 spring 模拟测试上述控制器。
package org.rw.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.rw.service.UserService;
import org.rw.test.SpringControllerTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
public class PersonControllerTest extends SpringControllerTest {
@Autowired
private UserService userService;
@Test
public void add() throws Exception {
mockMvc.perform(get("/person/add", new Object[0])).andExpect(status().isOk());
}
@Test
public void save() throws Exception {
UserDetails userDetails = userService.findByUsername("anil");
Authentication authToken = new UsernamePasswordAuthenticationToken (userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authToken);
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrl("view")
);
}
}
now here i have a problem that redirectedUrl("view")
is rejecting value "view/5"
. I have tried redirectedUrl("view*")
and redirectedUrl("view/*")
but its not working.
现在我有一个redirectedUrl("view")
拒绝 value的问题"view/5"
。我试过了redirectedUrl("view*")
,redirectedUrl("view/*")
但它不起作用。
Edit :
编辑 :
Here I have got a workaround as per below
在这里,我有一个解决方法,如下所示
MvcResult result = mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "MALE")
.param("dob", "11/02/1989")
).andExpect(
//redirectedUrl("view")
status().isMovedTemporarily()
).andReturn();
MockHttpServletResponse response = result.getResponse();
String location = response.getHeader("Location");
Pattern pattern = Pattern.compile("\Aview/[0-9]+\z");
assertTrue(pattern.matcher(location).find());
but still i am looking for the proper way.
但我仍然在寻找正确的方法。
update:
更新:
I have posted the same issue on spring jira here:
我在spring jira上发布了同样的问题:
回答by Roman Konoval
Since spring 4.0 you can use redirectedUrlPatternas pointed by Paulius Matulionis
由于弹簧4.0可以使用redirectedUrlPattern由尖的Paulius Matulionis
As of spring 3.x this is not supported out of the box but you can easily add you custom result matcher
从 spring 3.x 开始,这不支持开箱即用,但您可以轻松添加自定义结果匹配器
private static ResultMatcher redirectedUrlPattern(final String expectedUrlPattern) {
return new ResultMatcher() {
public void match(MvcResult result) {
Pattern pattern = Pattern.compile("\A" + expectedUrlPattern + "\z");
assertTrue(pattern.matcher(result.getResponse().getRedirectedUrl()).find());
}
};
}
And use it like build-in matcher
并像内置匹配器一样使用它
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrlPattern("view/[0-9]+")
);