MyControllerClassNameHandlerMapping.java
package com.qiyongkang.sys.controller;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.support.AbstractControllerUrlHandlerMapping;
/**
* ClassName:MyControllerClassNameHandlerMapping
* Function: TODO ADD FUNCTION.
* Reason: TODO ADD REASON.
* Date: 2015年10月25日 下午5:03:01
* @author qiyongkang
* @version
* @since JDK 1.6
* @see
*/
public class MyControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping {
/**
* 是否区分大小写
*/
private boolean caseSensitive = false;
/**
* ctrl所在包路径的前缀
*/
private String[] frameworkPackagePrefixs = new String[] {"com.qiyongkang."};
/**
* ctrl的类后缀
*/
private String[] actionClassSuffixs = new String[]{"Ctrl", "Controller"};
/**
* ctrl所在包路径的后缀
*/
private String[] actionPackageSuffixs = new String[] {"ctrl", "controller"};
/**
* 构造器
*/
public MyControllerClassNameHandlerMapping() {
super();
}
@SuppressWarnings("rawtypes")
@Override
protected String[] buildUrlsForHandler(String beanName, Class beanClass) {
System.out.println("beanName:" + beanName + ",beanClass:" + beanClass.getName());
//请求路径前缀
StringBuilder pathMapping = buildPathPrefix(beanClass);
System.out.println("pathMapping:" + pathMapping);
//获取类名
String className = ClassUtils.getShortName(beanClass);
//请求路径后缀
String path = getEndWithSuffixPath(className, actionClassSuffixs);
System.out.println("path:" + path);
if (path.length() > 0) {
if (this.caseSensitive) {
pathMapping.append(path.substring(0, 1).toLowerCase()).append(path.substring(1));
}
else {
pathMapping.append(path.toLowerCase());
}
}
//最终转换后的请求url路径
String[] finalPath = null;
if (isMultiActionControllerType(beanClass)) {
finalPath = new String[] {pathMapping.toString(), pathMapping.toString() + "/*"};
}
else {
finalPath = new String[] {pathMapping.toString() + "*"};
}
for (String str : finalPath) {
System.out.println(str);
}
return finalPath;
}
/**
*
* buildPathPrefix:生成请求前缀.
*
* @author qiyongkang
* @param beanClass
* @return
* @since JDK 1.6
*/
@SuppressWarnings("rawtypes")
private StringBuilder buildPathPrefix(Class beanClass) {
StringBuilder pathMapping = new StringBuilder();
pathMapping.append("/");
//在这里加入自己的URL映射逻辑规范
pathMapping.append(buildPathByBeanClass(beanClass, frameworkPackagePrefixs, actionPackageSuffixs, caseSensitive));
return pathMapping;
}
/**
*
* buildPathByBeanClass:根据类名称和包名称来组成自定义的URL映射.
*
* @author qiyongkang
* @param beanClass
* @param frameworkPackagePrefixs
* @param actionPackageSuffixs
* @param caseSensitive
* @return
* @since JDK 1.6
*/
@SuppressWarnings("rawtypes")
private String buildPathByBeanClass(Class beanClass, String[] frameworkPackagePrefixs, String[] actionPackageSuffixs, boolean caseSensitive) {
String packageName = ClassUtils.getPackageName(beanClass);
if (StringUtils.isEmpty(packageName)) {
return "";
}
String actionPackageSuffix = "";
for (String packageSuffix : actionPackageSuffixs) {
if (packageName.endsWith(packageSuffix)) {
actionPackageSuffix = packageSuffix;
break;
}
}
String newpackageName="";
for (String frameworkPackagePrefix : frameworkPackagePrefixs) {
if (packageName.startsWith(frameworkPackagePrefix)) {
newpackageName = StringUtils.replace(packageName, frameworkPackagePrefix, "");
// break;
}
}
newpackageName = StringUtils.replace(newpackageName, actionPackageSuffix, "");
newpackageName = StringUtils.replace(newpackageName, ".", "/");
return (caseSensitive ? newpackageName : newpackageName.toLowerCase()) + "/";
}
/**
*
* getEndWithSuffixPath:根据类后缀数组筛选出path的结果.
*
* @author qiyongkang
* @param className
* @param suffixs
* @return
* @since JDK 1.6
*/
private String getEndWithSuffixPath(String className, String[] suffixs) {
String path = "";
for (String suffix : suffixs) {
if (className.endsWith(suffix)) {
path = className.substring(0, className.lastIndexOf(suffix));
break;
}
}
return StringUtils.isEmpty(path) ? className : path;
}
public boolean isCaseSensitive() {
return caseSensitive;
}
public void setCaseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
public String[] getFrameworkPackagePrefixs() {
return frameworkPackagePrefixs;
}
public void setFrameworkPackagePrefixs(String[] frameworkPackagePrefixs) {
this.frameworkPackagePrefixs = frameworkPackagePrefixs;
}
public String[] getActionClassSuffixs() {
return actionClassSuffixs;
}
public void setActionClassSuffixs(String[] actionClassSuffixs) {
this.actionClassSuffixs = actionClassSuffixs;
}
public String[] getActionPackageSuffixs() {
return actionPackageSuffixs;
}
public void setActionPackageSuffixs(String[] actionPackageSuffixs) {
this.actionPackageSuffixs = actionPackageSuffixs;
}
}
spring-mvc.xml:
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<context:component-scan base-package="com.qiyongkang.**.controller" />
<mvc:resources location="/resources/**" mapping="/resources/**" />
<beans:bean id="myControllerClassNameHandlerMapping" class="com.qiyongkang.sys.controller.MyControllerClassNameHandlerMapping">
<beans:property name="interceptors">
<beans:array>
<beans:bean id="sysLogInterceptor" class="com.qiyongkang.sys.interceptor.SysLogInterceptor">beans:bean>
beans:array>
beans:property>
<beans:property name="caseSensitive" value="true" />
<beans:property name="frameworkPackagePrefixs" value="com.qiyongkang." />
<beans:property name="actionPackageSuffixs" value=".ctrl,.controller" />
<beans:property name="actionClassSuffixs" value="Ctrl,Controller" />
beans:bean>
<beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:property name="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8beans:value>
beans:list>
beans:property>
beans:bean>
<beans:bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
<beans:bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<beans:property name="supportedMediaTypes">
<beans:list>
<beans:value>application/json;charset=UTF-8beans:value>
beans:list>
beans:property>
beans:bean>
beans:list>
beans:property>
beans:bean>
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
beans:bean>
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="defaultEncoding" value="UTF-8" />
<beans:property name="maxInMemorySize" value="10240" />
<beans:property name="maxUploadSize" value="-1" />
beans:bean>
beans:beans>
beanId为myControllerClassNameHandlerMapping的类,便是我们将所有controller的请求按照自己的约定方式生成请求路径的处理类。
首先,我们来看看,我们的两个controller类。
UserController.java:
package com.qiyongkang.sys.controller;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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 org.springframework.web.servlet.view.RedirectView;
import com.qiyongkang.sys.model.User;
import com.qiyongkang.sys.service.UserService;
import com.qiyongkang.sys.util.Page;
@Controller
@RequestMapping
public class UserController extends BaseController{
private static Logger log = Logger.getLogger(UserController.class);
@Autowired
private UserService userService;
@RequestMapping
public ModelAndView login(HttpServletRequest request) {
ModelAndView mav = new ModelAndView(new RedirectView(request.getContextPath() + "/index.jsp"));
HttpSession session = request.getSession();
session.setAttribute("user", new User());
return mav;
}
@RequestMapping
@ResponseBody
public Page getPageModel(User user, int page, int rows) {
Page pageModel = new Page();
try {
user.setCurrentPage(page);
user.setPageSize(rows);
//Get total
int total = userService.getUserCount(user);
pageModel.setTotal(total);
//Get list
List users = userService.listUser(user);
pageModel.setRows(users);
} catch (Exception e) {
log.error("分页信息失败",e);
}
return pageModel;
}
@RequestMapping
@ResponseBody
public List getUserList() {
User user = new User();
user.setCurrentPage(1);
user.setPageSize(10);
return userService.listUser(user);
}
@RequestMapping
@ResponseBody
public User getEntity(int id) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return userService.getUserById(id);
}
@RequestMapping
@ResponseBody
public void editEntity(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Edit user:" + user);
userService.updateUser(user);
}
@RequestMapping
@ResponseBody
public void addEntity(User user) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Add user:" + user);
userService.addUser(user);
}
@RequestMapping
@ResponseBody
public void deleteEntity(@RequestParam(value = "ids[]", required=true) int[] ids) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ids);
List nums = new ArrayList();
for (int i : ids) {
nums.add(i);
}
userService.deleteUser(nums);
}
}
RedirectCtrl.java:
package com.qiyongkang.sys.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping
public class RedirectCtrl extends BaseController {
@RequestMapping
public ModelAndView redirectHomePage(String path) {
ModelAndView mav = new ModelAndView(path);
return mav;
}
}
最后,再来看看控制台输出的请求路径格式:
这样,我们在前端请求后台时,只需发送如下格式的请求,例如:
http://localhost:8080/qyk_testSpringMVC/sys/user/getPageModel.do
关于通配url请求就讲到这儿啦,它的好处可想而知,以后无需在@RequestMapping中指定值,同时也可以按照一定的规则来配置整个后台请求的格式,方便前端调用。
另外,哪位小伙伴有啥疑问的,都可以给我留言,谢谢!