javax.servlet.ServletException:循环视图路径[产品]

时间:2018-08-14 09:16:51

标签: spring spring-mvc spring-boot

我是Java Spring 4.0中的新手。这是我的项目设置。

enter image description here

ProductController

@Controller
public class ProductController {

private ProductService productService;

@Autowired
public void setProductService(ProductService productService) {
    this.productService = productService;
}

@RequestMapping("/products")
public String listProducts(Model model){

    model.addAttribute("products",productService.listAllProducts());

    return "products";
}

@RequestMapping("product/{id}")
public String getProduct(@PathVariable Integer id, Model model){

    model.addAttribute("product", productService.getProductById(id));

    return "product";
}

@RequestMapping("product/edit/{id}")
public String edit(@PathVariable Integer id, Model model){

    model.addAttribute("product",productService.getProductById(id));

    return "productform";
}

@RequestMapping("/product/new")
public String newProduct(Model model){
    model.addAttribute("product",new Product());
    return "productform";
}

@RequestMapping(value = "/product", method = RequestMethod.POST)
public String saveOrUpdateProduct(Product product){

    Product saveProduct = productService.saveOrUpdateProduct(product);
    return "redirect:/product/" + saveProduct.getId();

}

@RequestMapping("/product/delete/{id}")
public String delete(@PathVariable Integer id){

    productService.deleteProduct(id);

    return "redirect:/products";
  }
}

ProductServiceImpl

@Service 
public class ProductServiceImpl implements ProductService {

Map<Integer, Product> products;

public ProductServiceImpl(){
    loadProducts();
}

@Override
public List<Product> listAllProducts() {
    return new ArrayList<>(products.values());
}

@Override
public Product getProductById(Integer id) {
    return products.get(id);
}

@Override
public Product saveOrUpdateProduct(Product product) {

    if (product != null){
        if (product.getId() == null){
            product.setId(getNextKey());
        }

        products.put(product.getId(), product);

        return product;
    } else {
        throw new RuntimeException("Product Can't be nill");
    }
}

@Override
public void deleteProduct(Integer id) {
    products.remove(id);
}


private Integer getNextKey(){
    return Collections.max(products.keySet()) + 1;
}


private void loadProducts(){
    products = new HashMap<>();

    Product product1 = new Product();
    product1.setId(1);
    product1.setDescription("Product 1");
    product1.setPrice(new BigDecimal("12.99"));
    product1.setImageUrl("http://example.com/product1");

    products.put(1,product1);

    Product product2 = new Product();
    product2.setId(2);
    product2.setDescription("Product 2");
    product2.setPrice(new BigDecimal("14.99"));
    product2.setImageUrl("http://example.com/product2");

    products.put(2, product2);

    Product product3 = new Product();
    product3.setId(3);
    product3.setDescription("Product 3");
    product3.setPrice(new BigDecimal("34.99"));
    product3.setImageUrl("http://example.com/product3");

    products.put(3, product3);

    Product product4 = new Product();
    product4.setId(4);
    product4.setDescription("Product 4");
    product4.setPrice(new BigDecimal("44.99"));
    product4.setImageUrl("http://example.com/product4");

    products.put(4, product4);

    Product product5 = new Product();
    product5.setId(5);
    product5.setDescription("Product 5");
    product5.setPrice(new BigDecimal("25.99"));
    product5.setImageUrl("http://example.com/product5");

    products.put(5, product5);
   }
}

因此,我正在向控制器注入CRUD服务,并且运行良好。我可以发布,删除,显示和更新数据。现在我要进行模拟测试。所以。

ProductControllerTest

public class ProductControllerTest {

@Mock
private ProductService productService;

@InjectMocks
private ProductController productController;

private MockMvc mockMvc;

@Before
public void setup(){
    MockitoAnnotations.initMocks(this);

    mockMvc = MockMvcBuilders.standaloneSetup(productController).build();
}

@Test
public void testList() throws Exception{
    List<Product> products = new ArrayList<>();
    products.add(new Product());
    products.add(new Product());

    when(productService.listAllProducts()).thenReturn((List)products);

    mockMvc.perform(get("/products"))
            .andExpect(status().isOk())
            .andExpect(view().name("products"))
            .andExpect(model().attribute("products",hasSize(2)));

  }

}

不幸的是,测试未通过。

  

javax.servlet.ServletException:循环视图路径[产品]:将   再次分派回当前的处理程序URL [/ products]。检查你的   ViewResolver设置! (提示:这可能是由于未指定   视图,因为默认的视图名称生成。)

为什么会这样?我的意思是我可以在浏览器中显示产品,但是单元测试失败。

我正在使用弹簧靴和百里香模板。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>theo.tziomakas</groupId>
<artifactId>springmvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>springmvc</name>
<description>Demo project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>bootstrap</artifactId>
        <version>3.3.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>


</project>

1 个答案:

答案 0 :(得分:1)

请尝试使用@RequestMapping在ProductController的方法上添加@ResponseBody注释,如下所示。

@RequestMapping("/products")
@ResponseBody
public String listProducts(Model model){

    model.addAttribute("products",productService.listAllProducts());

    return "products";
}

希望这会有所帮助。