开发工具:idea
运行环境 :jetty
项目构建工具:maven
项目代码地址:https://github.com/ftinglee/ezssm.git
spring 结合spring mvc
添加maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
如果想知道具体哪个包有什么作用,详见
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/overview.html#overview-modules
配置web.xml
http://docs.spring.io/spring/docs/4.2.8.RELEASE/spring-framework-reference/htmlsingle/#mvc-config
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:ApplicationContext-MVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
新建spring mvc配置文件ApplicationContext-mvc.xml
<!--开启mvc注解-->
<mvc:annotation-driven enable-matrix-variables="true">
<!--配置消息转换器,解析@ResponseBody-->
<mvc:message-converters register-defaults="true">
<!-- 使用号称最快的json解析器的fastjson来对response body转换 -->
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="serializerFeatures">
<list>
<value>WriteMapNullValue</value>
<value>QuoteFieldNames</value>
<value>WriteDateUseDateFormat</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 开启controller注解支持,use-default-filters,不使用默认的扫描过滤配置 ,并且支持控制器增强advice-->
<context:component-scan base-package="ezbase.system" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
然后配置视图解析器
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="contentType" value="text/html"/>
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="com.alibaba.fastjson.support.spring.FastJsonJsonView" />
</list>
</property>
如果用到了多试图的话,可以使用ContentNegotiatingViewResolver
配置
并且还要处理静态资源,可以采用Web应用服务器默认的Servlet处理或者spring mvc提供的静态资源映射
<!--静态资源映射,js.css缓存一个月,img缓存三个月-->
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:resources mapping="/lib/**" location="/lib/" cache-period="72000"/>
<mvc:resources mapping="/css/**" location="/css/" cache-period="72000"/>
<mvc:resources mapping="/img/**" location="/img/" cache-period="216000"/>
<!--注意:这里不采用Web应用服务器默认的Servlet处理,使用上面的配置的spring mvc提供的静态资源映射-->
<!--<mvc:default-servlet-handler />-->
对于安全认证:可以采用shiro、spring security或者自己简单的写个过滤器
对于异常处理,会有很多选择,可以参照这篇博文
https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
<!--配置全局异常处理,继承自SimpleMappingExceptionResolver-->
<bean id="globalMappingExceptionResolver" class="ezbase.core.GlobalMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error</prop>
<prop key="java.lang.Throwable">error</prop>
</props>
</property>
<property name="defaultErrorView" value="error"/>
<property name="exceptionAttribute" value="exception"/>
<property name="warnLogCategory" value="ezbase.core.GlobalMappingExceptionResolver"/>
</bean>
其中异常处理逻辑,是通过前台请求是否为ajax或者content_type为json,然后判断返回错误页面还是返回数据
public class GlobalMappingExceptionResolver extends SimpleMappingExceptionResolver{
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = super.doResolveException(request, response, handler, ex);
ex.toString();
modelAndView.addObject("url", request.getRequestURL());
if (!(request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With")!= null
&& request.getHeader("X-Requested-With").contains("XMLHttpRequest") ))) {
return modelAndView;
}else {
try {
PrintWriter writer = response.getWriter();
modelAndView.addObject("url",request.getRequestURI());
modelAndView.addObject("msg","noe permission");
writer.write(JSON.toJSONString(modelAndView));
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
其中前台页面错误处理的方式参考了https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
使用注释的方式,对于线上出问题,不用老是去瞅日志了,汗,以前我怎么没有想到
<h1>错误页面</h1>
<p>程序发生了错误,请尽快联系管理员...</p>
<!--
请求地址: ${url}
异常类型: ${exception}
异常信息: ${exception.message}
<c:forEach items="${exception.stackTrace}" var="ste">${ste}
</c:forEach>
-->
当然,对于404 这种错误 spring mvc还是无法处理的
还是乖乖使用使用默认的sevlet 容器在web.xml处理了
<!--404 错误页面-->
<error-page>
<error-code>404</error-code>
<location>/static/404.html</location>
</error-page>
最后便是功能的完善逻辑处理及前台页面的编写
补充:忘记很重要的一点:日志
可以使用log4j slf4j等等