知识点:
1.优雅REST风格的资源URL不希望带 .html 或 .do 等后缀(如实现直接访问www.xxx.com/know/ 这样的链接)。由于早期的Spring MVC不能很好地处理静态资源,所以在web.xml中配置DispatcherServlet的请求映射,往往使用 *.do 、 *.htm、*.xhtml等方式。这就决定了请求URL必须是一个带后缀的URL,而无法采用真正的REST风格的URL。
由于REST是Spring3.0最重要的功能之一,所以Spring团队很看重静态资源处理这项任务,给出了堪称经典的两种解决方案。先调整web.xml中的DispatcherServlet的配置,使其可以捕获所有的请求:<url-pattern>/</url-pattern>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
通过上面url-pattern的配置,所有URL请求都将被Spring MVC的DispatcherServlet截获。
方法1.采用<mvc:default-servlet-handler /> 本实例使用
在springMVC-servlet.xml中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
方法2.采用<mvc:resources /> 略,自行学习
2.eclipse中使用maven方式使用jetty(可使用此标题搜索详细配置文章)
简略配置说明:pom.xml中build下plugins插件中添加如下实例配置,然后在项目右击Run As-Run_configuration配置如下图:
本地hosts文件中127.0.0.1 www.xxx.com配置一个网站域名访问
实例
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>com.citywy</groupId>
<artifactId>helloword</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- spring版本号 -->
<spring.version>4.2.5.RELEASE</spring.version>
<!-- mysql驱动版本号 -->
<mysql-driver.version>5.1.29</mysql-driver.version>
<!-- log4j日志包版本号 -->
<slf4j.version>1.7.18</slf4j.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- 添加jstl依赖 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<!-- Freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
<!-- 添加junit4依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<!-- 指定范围,在测试时才会加载 -->
<scope>test</scope>
</dependency>
<!-- 添加spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 添加mysql驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-driver.version}</version>
</dependency>
<!-- 添加数据库连接池依赖 -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 添加fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<!-- 添加日志相关jar包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<!-- 映入JSON -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>
<!-- Apache上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build><!-- 配置使用jetty容器运行项目,直接使用tomcat部署运行和此处不冲突 -->
<finalName>helloworld</finalName>
<testSourceDirectory>src/test/java</testSourceDirectory>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<!-- http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin -->
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<stopPort>9966</stopPort>
<stopKey>foo</stopKey>
<scanIntervalSeconds>0</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>80</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<!-- Filter 定义处理中文乱码 -->
<!-- Character Encoding filter -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<display-name>helloworld</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置前端控制器,如果请求是以.htm结尾就走springmvc查找相应处理器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springmvc配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<!-- url模式与传统*.do *.htm等不同,rest风格是用 / 拦截所有访问链接进行处理 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd ">
<!-- 自动扫描包下面的文件,类上带有@Controller的会注册为bean -->
<context:component-scan base-package="com.citywy.controller"/>
<!-- 代替处理器映射器、处理器适配器 ,mvc注解驱动-->
<mvc:annotation-driven/>
<!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- Spring MVC上传文件时,我们都需要配置一个MultipartResolver的实现, 常用的是Apache提供的CommonsMultipartResolver类 -->
<!-- Spring MVC的核心类DispatcherServlet中, 把这些bean的id固定了. 你必须保证bean的id相同, 才能正常工作. -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!--max size: 10M 1024*1024*10-->
<property name="maxUploadSize" value="10485760"/>
</bean>
<!-- rest风格配置,静态资源处理 -->
<mvc:default-servlet-handler />
</beans>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.6.4.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello word</title>
</head>
<body>
<div>
<h2>${name}</h2>
</div>
</body>
</html>
TestController.java
package com.citywy.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class TestController {
/**
* 返回ModelAndView的方式,还有返回String的方式,传参方式通过ModelAndView
* http://www.helloworld.com/hello.html
*/
@RequestMapping("/hello")
public ModelAndView hello(HttpServletRequest request,HttpServletResponse response){
ModelAndView res=new ModelAndView("index");//这儿写法和springmvc.xml的文件跳转前后缀关联
res.addObject("name","你好,世界!");
return res;
}
}
ClassAnnotation.java
package com.citywy.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@Scope("prototype")
@RequestMapping("/know/") //类级别映射,一般用于减少书写量,该类所有注解方法的访问都会从/know/开始
public class ClassAnnotation {
/**
* 返回String的方法,传参方式通过HttpServletReqeust
* PathVariable路径变量,就是路径上的变量
* 访问:http://www.helloworld.com/know/12.htm
*/
@RequestMapping(value="{id:\\d+}")
public String detail(@PathVariable long id,HttpServletRequest request,HttpServletResponse response){
//如果不是以/know/xxx.html结尾的内页链接,301跳转到html或者返回404 (可能404情况多一些,看大站做法)
String uri=request.getRequestURI();
if(!uri.endsWith(".html")){
response.setStatus(301);
response.setHeader("Location", "//www.helloworld.com/know/"+id+".html");
return null;
}
System.out.println("输出文章id:"+id);
request.setAttribute("name", "这类似一个文章的内容页");
return "index";
}
/**
* 栏目页
* 接收/know/纯英文a-z小写的任意个数链接参数
* 接收访问:http://www.helloworld.com/know/myzs或http://www.helloworld.com/know/myzs/
* RequestMapping可以同时指定多个url,映射到同一个应答逻辑中:
* 如下:@RequestMapping(value={"","",""})
*/
@RequestMapping(value={"{code:[a-z]+}","{code:[a-z]+}/"})
public String list(@PathVariable String code,HttpServletRequest request,HttpServletResponse response){
//seo中栏目一般为 www.xxx.com/xxx/ 作为一个栏目页
String uri=request.getRequestURI();
if(!uri.endsWith("/")){
response.setStatus(301);
response.setHeader("Location", "//www.helloworld.com"+uri+"/");
return null;
}
System.out.println("输出栏目code:"+code);
request.setAttribute("name", "这类似一个文章的列表页");
return "index";
}
/**
* 栏目页分页
*/
@RequestMapping(value="{code:[a-z]+}/p{pageindex:\\d+}")
public String pageList(@PathVariable String code,@PathVariable int pageindex,HttpServletRequest request,HttpServletResponse response){
//seo中栏目分页为 www.xxx.com/xxx/p2.htm
System.out.println(code+"--"+pageindex);
request.setAttribute("name", "栏目"+code+"下第"+pageindex+"页");
return "index";
}
}
这是作者实际做web网站时候的简单注解开发方式缩略,文章有什么严重不足或与时代脱轨之处希望能在下方留言,或给些好的文章链接,让俺学习学习。