SpringMVC入门 - 利用java装配实现简单请求处理

0、pom.xml配置

<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>gensoku</groupId>
    <artifactId>TouhouProject</artifactId>
    <version>1.0</version>
    <packaging>war</packaging> <!-- 打包方式 -->

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <dependency> <!-- junit测试 -->
            <groupId>junit</groupId> 
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency> <!-- spring框架 -->
		    <groupId>org.springframework</groupId>  
		    <artifactId>spring-web</artifactId>  
		    <version>4.2.5.RELEASE</version>  
		</dependency>  

		<dependency>  
		    <groupId>org.springframework</groupId>  
		    <artifactId>spring-webmvc</artifactId>  
		    <version>4.2.5.RELEASE</version>  
		</dependency>

		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-context</artifactId>
		    <version>4.2.5.RELEASE</version>
		</dependency>

		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-test</artifactId>
		    <version>4.2.5.RELEASE</version>
		</dependency>

		<dependency><!-- AOP模块 -->
	    	<groupId>org.aspectj</groupId> 
	    	<artifactId>aspectjrt</artifactId>
	    	<version>1.9.1</version>
	    </dependency>
	    
	    <dependency>
	    	<groupId>org.aspectj</groupId>
	    	<artifactId>aspectjweaver</artifactId>
	    	<version>1.9.1</version>
	    </dependency>

        <dependency> <!-- tomcat大概需要 -->
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency> <!-- jsp解析 -->
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
   </dependencies>

    <repositories>  
            <repository> <!-- 远程仓库 -->  
                <id>alimaven</id>  
                <name>aliyun maven</name>  
                <url>http://maven.aliyun.com/nexus/content/groups/public/</url>  
                <releases>  
                    <enabled>true</enabled>  
                </releases>  
                <snapshots>  
                    <enabled>false</enabled>  
                </snapshots>  
            </repository>  
    </repositories>

    <build>
        <plugins>
            <plugin> <!-- tomcat插件配置 -->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <hostName>localhost</hostName>
                    <port>8080</port>
                    <uriEncoding>UTF-8</uriEncoding>
                </configuration>
            </plugin>

            <plugin> <!-- 模块测试的配置 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.10</version>
                <configuration>
                    <includes>
                        <include>**/hellotest.java</include>
                    </includes>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <warSourceDirectory>WebContent</warSourceDirectory>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>

        <resources>
            <resource> <!-- 静态文件打包配置 -->
                <directory>F:/java_demo/rumia_spring_web/pages</directory>
                <includes>
                    <include>*.html</include>
                    <include>*.jsp</include>
                </includes>
                <targetPath>pages</targetPath> 
            </resource>
        </resources>
    </build>
</project>

1、Servlet前端控制器
拦截请求并分发至控制器、视图解析器等进行处理。
由两种应用上下文组成。

package gensoku;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

//前端servlet
public class myServlet extends AbstractAnnotationConfigDispatcherServletInitializer
{
    @Override
    protected String[] getServletMappings() //拦截映射
    {
        return new String[]{ "/" };
    }

    @Override 
    protected Class<?>[] getServletConfigClasses()  //web配置
    {
        return new Class<?>[] { webConfig.class };
    }

    @Override
    protected Class<?>[] getRootConfigClasses() //其他组件配置
    {
        return new Class<?>[] { rootConfig.class };
    }
}

2、rootConfig上下文
一般是驱动应用后端的中间层和数据层组件。

package gensoku;

import org.springframework.beans.factory.annotation.Configurable;

@Configurable
public class rootConfig 
{
    
}

3、webConfig上下文
一般是控制器、视图解析器及处理器映射。

package gensoku;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import gensoku.data.newsData;
import gensoku.data.newsDataHub;

@Configuration
@EnableWebMvc
//@ComponentScan("gensoku")
public class webConfig extends WebMvcConfigurerAdapter
{
    @Bean //控制器
    public myController retController()
    {
        return new myController(retDatahub());
    }

    @Bean //数据读写器,插入4条数据进行测试
    public newsDataHub retDatahub()
    {
        newsDataHub testhub = new newsDataHub();
        testhub.addNewsData(new newsData(1, "day 1", "Rumia eats people"));
        testhub.addNewsData(new newsData(2, "day 2", "Yokali hides people"));
        testhub.addNewsData(new newsData(3, "day 3", "UUZ kills people"));
        testhub.addNewsData(new newsData(4, "day 4", "Reimu beats people"));
        return testhub;
    }

    @Bean //视图解析器
    public ViewResolver viewResolver()
    {
        InternalResourceViewResolver rs = new InternalResourceViewResolver();
        rs.setPrefix("/WEB-INF/classes/pages/"); //增加资源路径前缀
        rs.setExposeContextBeansAsAttributes(true);
        return rs;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer con)
    {
        con.enable(); //允许静态资源由默认servlet处理
    }
}

4、Controller
控制器根据映射处理servlet传过来的请求,并将处理结果(主要是ModelAndView,包括视图名和模型数据)返回给视图解析器处理。
控制器即MVC的C,视图即V,模型即M.

package gensoku;

import static org.springframework.web.bind.annotation.RequestMethod.*;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import gensoku.data.newsDataHub;

@Controller
public class myController 
{
    private newsDataHub dataHub;

    public myController()
    {
        dataHub = null;
    }

    public myController(newsDataHub ndh)
    {
        dataHub = ndh;
    }

    @RequestMapping(value = "/", method = GET) //请求映射,包括地址和方法
    public String getHome()
    {
        System.out.println("GET : /home");
        return "home.html"; //直接返回视图名
    }

    @RequestMapping(value = "/news", method = GET) //地址包含请求的参数(id)
    public ModelAndView getNews(@RequestParam(value="id", required=false, defaultValue= "1") int id)
    {
        System.out.println("GET : /news id=" + id);
        ModelAndView mv = new ModelAndView();
        mv.setViewName("newslist.jsp"); //定义视图名
        mv.addObject("newsName", dataHub.findNewsData(id).getName()); //以键值对方式加入模型数据
        mv.addObject("newsContent", dataHub.findNewsData(id).getContent());
        return mv; //返回视图及模型数据
    }

    @RequestMapping(value = "/secret/{magicNum}", method = GET) //地址以占位符形式包含路径参数
    public ModelAndView checkSecret(@PathVariable("magicNum") int N)
    {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("secret.jsp");
        mv.addObject("waitnum", N);
        if(N == 514114)
            mv.addObject("ans", "Right!");
        else
            mv.addObject("ans", "Wrong!");
        return mv;
    }
}

5、模块测试
主要对控制器进行了测试。

package gensoku;

import org.junit.Test;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
import org.springframework.test.web.servlet.MockMvc;

import gensoku.data.newsData;
import gensoku.data.newsDataHub;

public class hellotest
{
	@Test
	public void testing() throws Exception
	{
		System.out.println("---testing---");
		newsDataHub ndh = new newsDataHub(); //定义并初始化数据读取器
		for(int i=0; i<10; i++)
		{
			ndh.addNewsData(new newsData(i, "rumia_"+i, "^-^"));
		}
		myController mc = new myController(ndh);
		MockMvc mc_test = standaloneSetup(mc).build(); //针对控制器生成mock
		mc_test.perform(get("/")).andExpect(view().name("home.html")); //利用mock对控制器进行请求,并校验其返回视图名
		mc_test.perform(get("/news?id=2")).andExpect(view().name("newslist.jsp"))
								.andExpect(model().attributeExists("newsName")); //校验模型数据是否包含某键
		mc_test.perform(get("/secret/1234")).andExpect(view().name("secret.jsp"))
								.andExpect(model().attributeExists("ans"));
	}
}

6、JSP及tomcat服务器测试
利用java装配就不需要web.xml,但是tomcat版本需要在7以上。
为了方便测试没有搭建完整的服务器,而是利用了maven的tomcat插件直接嵌入执行,需要利用pom中的resource标签打包静态文件(html和jsp等)。
这里利用jsp进行简单渲染(直接将控制器返回的ModelAndView数据填上了),代码结构大概如下:

<head></head>
<body>
	<h1>Fake News</h1>
	<br>
		Name : ${requestScope.newsName}
	<br>
		Content : ${requestScope.newsContent}
	<br>	
</body>

这里的一个大坑在于,如果测试时直接命令:
mvc clean tomcat7:run
只是将mvc代码嵌入tomcat执行,不会将静态资源打包进去,因此读取静态资源都会出现404的情况,因此测试时需要先打包成war再强制其读取war执行:
mvc clean package tomcat7:run-war-only
这样就可以读取静态资源了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值