一、使用maven和intellij构造spring mvc程序的步骤和方法:
1.使用如下命令创建一个名为CounterWebApp的web应用。
mvn archetype:generate -DgroupId=com.chf -DartifactId=CounterWebApp -DarchetypeArtifactId=maven-archetype-webapp
-DinteractiveMode=false
2.在CounterWebApp/src/main/java目录下面创建你的源代码的包目录和文件。
3.在pom.xml中配置spring mvc需要添加的依赖。
如下面的代码所示:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chf</groupId>
<artifactId>CounterWebApp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>CounterWebApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<jdk.version>1.7</jdk.version>
<spring.version>4.1.1.RELEASE</spring.version>
<jstl.version>1.2</jstl.version>
<junit.version>4.11</junit.version>
<logback.version>1.0.13</logback.version>
<jcl-over-slf4j.version>1.7.5</jcl-over-slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--spring core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl-over-slf4j.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.3</version>
<classifier>jdk15</classifier>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
</dependencies>
<build>
<!--最终生成的war文件名-->
<finalName>CounterWebApp</finalName>
<plugins>
<!-- Set JDK Compiler Level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>GBK</encoding>
</configuration>
</plugin>
<!-- For Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!--Deploy to server-->
<url>http://localhost:8080/manager/text</url>
<server>Tomcat7Server</server>
<path>/CounterWebApp</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
4.然后使用mvn clean && mvn install来运行程序。
5.遇到的问题和解决方法:
1)mvn install过程中遇到下面的错误:
Fatal error compiling: ??Ч??Ŀ??汾?? 1.7 -> [Help 1]
解决方法:
在~/.bash_profile文件中添加下面配置。添加完后,运行source ~/.bash_profile。
alias javac='javac -J-Dfile.encoding=UTF-8 -encoding UTF-8'
alias java='java -Dfile.encoding=UTF-8'
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
2)这样之后,再次mvn install的时候遇到错误:Fatal error compiling: invalid target release: 1.7
解决方法:
在~/.bash_profile文件中添加一行下面的配置。添加完后,运行source ~/.bash_profile。
export JAVA_HOME='/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home'
二、创建第一个spring mvc的程序。
1.我对spring mvc的理解:
1)spring mvc的结构主要包括下面几个部分:
DispatcherServlet:将请求转发给控制器。
Controller:具体地处理请求。
Handler Mapping:映射处理器,负责映射中央处理器,转发给Controller时的映射策略。
ModelAndView:服务器返回的数据和视图层的封装类。
ViewResolver&View:视图解析器、解析具体的视图。
Interceptors:拦截器,负责拦截我们定义的请求,然后做处理工作。
2)spring mvc具体的处理流程如下图所示:
2.例子的目的:在web程序中,存在一类程序,其服务端端的处理时间比较长。正因处理时间比较长,因此这类程序有可能会导致请求超时。对于这种应用程序经常使用异步请求的方式来解决。之前没有使用过这种方式,因此首先写一个极其简单的程序。
这个程序的目的是:使用ajax的方式,每隔1s就发送一个请求到服务端。服务端会计数,如果计数达到20就返回一个finish给客户端(表示服务端的任务完成),如果客户端接收到服务端任务完成的讯息,就停止发送请求。
3.例子的具体实现:
直接上代码和各个配置文件的配置
1)Controller类:
package com.chf.controller;
import com.chf.services.AsyncServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.chf.util.ResoponseUtil;
/**
* Created by Administrator on 15-1-31.
*/
/*There must be a Controller annotation or the application will doesn't work .*/
@Controller
public class BaseController {
@Autowired
AsyncServiceImpl asyncService;
@Autowired ResoponseUtil ResponseUtil;
// @RequestMapping(value = "async/{key}")
@RequestMapping(value = "{key}")
//async/{key}?
public String asyncTest(HttpServletRequest req,
HttpServletResponse resp, @PathVariable String key) throws Exception {
asyncService.asyncMethod(key);
return "common/async";
}
//@RequestMapping(params= "method=getStatus",method = RequestMethod.GET)
@RequestMapping("/status")
public String showAsyncStatus(HttpServletRequest req,
HttpServletResponse resp) throws Exception {
// HttpServletResponse resp, @PathVariable String key) throws Exception {
System.out.println("in status new!!");
String status = asyncService.getProcess(null);
ResponseUtil.OutputJson(resp, "{\"status\":\"" + status + "\"}");
return null;
}
@RequestMapping(value = "/clear")
public String clearAsyncStatus(HttpServletRequest req,
HttpServletResponse resp, @PathVariable String key) throws Exception {
asyncService.clearCache(key);
ResponseUtil.OutputJson(resp, "{\"status\":\"ok\"}");
return null;
}
}
2)service接口和service方法:
package com.chf.services;
/**
* Created by hfc on 15/10/21.
*/
public interface AsyncService {
void asyncMethod(String cacheKey) throws Exception;
public String getProcess(String cacheKey) throws Exception;
public void clearCache(String cacheKey) throws Exception;
}
package com.chf.services;
/**
* Created by hfc on 15/10/21.
*/
import com.chf.services.AsyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service("asyncService")
public class AsyncServiceImpl implements AsyncService {
// @Autowired
// StringRedisTemplate stringRedisTemplate;
Integer count = 0;
@Override
@Async
public void asyncMethod(String cacheKey) throws Exception {
int maxStep = 20;
for (int i = 0; i < maxStep; i++) {
Thread.sleep(2000);
count++;
//stringRedisTemplate.opsForValue().set(cacheKey, (i + 1) + "/" + maxStep);
}
}
@Override
public String getProcess(String cacheKey) throws Exception {
count++;
if(count>=20)
return "finish";
return null;
}
@Override
public void clearCache(String cacheKey) throws Exception {
//stringRedisTemplate.delete(cacheKey);
count = 0;
}
}
3)index.jsp:
<html>
<head>
<script src="ui/js/jquery.js"></script>
</head>
<script type="text/javascript" language="JavaScript">
var timerId = null;//?????ID
$(document).ready(function () {
// alert("ready!");
/*
????????н??
*/
timerId = setInterval(function () {
getStatus();
}, 1000);
getStatus();
});
/**
?????н??
*/
function getStatus() {
var statusUrl = window.location.href + "/status";
// alert("asdf");
$.get(statusUrl, function (data) {
if (data == null || data.status == null || data.status == "null") {
updateStatus("ready");
return;
}
var status = data.status;
updateStatus(status);
alert("before clear");
clearInterval(timerId);//???????
alert("after clear");
// var temp = status.split("/");
// if (temp[0] == temp[1]) {
// updateStatus("finish");
// clearInterval(timerId);//???????
// clearStatus();//????redis????
// }
})
}
/**
* ?????????????
*/
function clearStatus() {
var clearStatusUrl = window.location.href + "/clear";
$.get(clearStatusUrl, function (data) {
//alert(data.status);
})
}
/**
?????????
*/
function updateStatus(msg) {
$("#status").html(msg);
}
</script>
<div id="msgBox">
<span>begin processing</span>
<h1>current task:<span style="color:red" id="status">ready</span></h1>
</div>
<body>
</body>
</html>
4)配置文件:
web.xml:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Counter Web Application </display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
mvc-dispatch-servlet.xml文件:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Counter Web Application </display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
4.启动tomcat,并在浏览器中输入localhost:8080即可。
三、注意点:
1、服务端返回json数据的格式:
1)返回数据的时候将MIMETYPE设置为:
response.setContentType("application/json;charset=utf-8");
2)JSON 数据的书写格式是:名称/值对。
名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值:
"firstName" : "John"因此服务端在返回的时候要注意双引号。否则浏览器解析的结果不正确。
2、web.xml中通过如下来配置其Context的文件名称。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value><span style="color:#ff6666;">/WEB-INF/mvc-dispatcher-servlet.xml</span></param-value>
</context-param>
3.使用注解的方式来使用bean的时候,需要在mvc-dispatcher-servlet.xml配置相关的bean。只有配置后,才能使用。
4.在web.xml中有如下的配置:
<servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>这样所有的url都会被controller拦截。以致于在index.jsp中找不到jquery.js资源。
为了解决这个问题:添加了一个资源拦截配置如下:
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping>
5.请求过程中遇到400错误,都是因为请求的参数和服务端的参数不一致造成的。