SpringMVC的使用
前言
以下内容为实习需要,特作整理,因为经验不足,如有错误,欢迎指正!
HandlerMapping
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MBhrKJyB-1595743594186)(SpringMVC%E7%9F%A5%E8%AF%86%E6%B1%87%E6%80%BB.assets/image-20200726082623817.png)]
处理器映射器,主要用来查找handler(这里的handler就是通常所说的Controller)并返回,至于怎么找到的handler可以参照我之前写的一篇博客:SpringMVC执行流程源码分析,里边介绍了SpringMVC的执行流程以及查找好handler的过程,今天主要介绍这些handler的区别于作用:
1.BeanNameUrlHandlerMapping根据bean标签的名字找到相对应的Controller类
2.SimpleUrlHandlerMapping 根据bean的id查找对应的Controller类
3.ControllerClassNameHandlerMapping根据bean的类名找相对应的Controller类
RequestMapping
此注解主要用来处理HTTP请求,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求
SpringMVC参数传递
一:直接将请求参数名作为Controller中方法的形参
public String login (String username,String password) :
解释:括号中的参数必须与页面Form 表单中的 name 名字相同
二:使用@RequestParam 绑定请求参数参数值
举例:public String login(RequestParam (“username”) String name) :
解释:双引号中的username 必须与页面 name 名字相同,String name 中的name可以随便写
三:用注解@RequestMapping接收参数的方法
@RequestMapping(value="/login/{username}/{password}")
public String login(@PathVariable(“username”) String name,@PathVariable(“password”) String name)
解释:上面的 @RequestMapping(value="/login/{username}/{password}") 是以注解的方式写在方法上的。注解上的usernname和 password 必须好页面上name 相同
四:使用Pojo对象(就是封装的类,类中封装的字段作为参数)绑定请求参数值,原理是利用Set的页面反射机制找到User对象中的属性
举例:@ReauestMapping(value=/login”)
public String login(User user){
解释:就是把封装的一个类当成一个参数放在方法中,封装类中的属性就是就是参数。
五:使用原生的Servlet API 作为Controller 方法的参数
public String login(HttpServletRequest request){
String usernma=Request.getParameter(“username”);
}
解释:使用request 请求页面参数的方式获取从页面传过来的参数
参数传递原理解析:
- 首先再DispatcherServlet的doDispatch()中执行了:mv = ha.handle(processedRequest, response, mappedHandler.getHandler());来执行handler
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
- 继续往下走
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
mav = invokeHandlerMethod(request, response, handlerMethod);
执行handler的方法
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod):获取参数绑定的工厂
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);获取Model工厂
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod):创建执行handler的方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);执行handler方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);调用这个方法来执行request
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
return doInvoke(args);
}
它首先根据Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);获取了方法的参数值
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//获取方法参数
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
catch (Exception ex) {
// Leave stack trace for later, exception may actually be resolved and handled...
if (logger.isDebugEnabled()) {
String exMsg = ex.getMessage();
if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
logger.debug(formatArgumentError(parameter, exMsg));
}
}
throw ex;
}
}
return args;
}
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
来解析参数值
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
//获取参数解析器
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unsupported parameter type [" +
parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
}
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);解析参数
resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
@Override
@Nullable
public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
String name = ModelFactory.getNameForParameter(parameter);
ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
if (ann != null) {
mavContainer.setBinding(name, ann.binding());
}
Object attribute = null;
BindingResult bindingResult = null;
if (mavContainer.containsAttribute(name)) {
attribute = mavContainer.getModel().get(name);
}
else {
// Create attribute instance
try {
attribute = createAttribute(name, parameter, binderFactory, webRequest);
}
catch (BindException ex) {
if (isBindExceptionRequired(parameter)) {
// No BindingResult parameter -> fail with BindException
throw ex;
}
// Otherwise, expose null/empty value and associated BindingResult
if (parameter.getParameterType() == Optional.class) {
attribute = Optional.empty();
}
bindingResult = ex.getBindingResult();
}
}
if (bindingResult == null) {
// Bean property binding and validation;
// skipped in case of binding failure on construction.
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
if (binder.getTarget() != null) {
if (!mavContainer.isBindingDisabled(name)) {
bindRequestParameters(binder, webRequest);
}
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
// Value type adaptation, also covering java.util.Optional
if (!parameter.getParameterType().isInstance(attribute)) {
attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
}
bindingResult = binder.getBindingResult();
}
// Add resolved attribute and BindingResult at the end of the model
Map<String, Object> bindingResultModel = bindingResult.getModel();
mavContainer.removeAttributes(bindingResultModel);
mavContainer.addAllAttributes(bindingResultModel);
return attribute;
}
attribute = createAttribute(name, parameter, binderFactory, webRequest);在这创建的绑定对象
attribute = createAttribute(name, parameter, binderFactory, webRequest);
@Override
protected final Object createAttribute(String attributeName, MethodParameter parameter,
WebDataBinderFactory binderFactory, NativeWebRequest request) throws Exception {
String value = getRequestValueForAttribute(attributeName, request);
if (value != null) {
Object attribute = createAttributeFromRequestValue(
value, attributeName, parameter, binderFactory, request);
if (attribute != null) {
return attribute;
}
}
return super.createAttribute(attributeName, parameter, binderFactory, request);
}
return super.createAttribute(attributeName, parameter, binderFactory, request);
protected Object createAttribute(String attributeName, MethodParameter parameter,
WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception {
MethodParameter nestedParameter = parameter.nestedIfOptional();
Class<?> clazz = nestedParameter.getNestedParameterType();
Constructor<?> ctor = BeanUtils.findPrimaryConstructor(clazz);
if (ctor == null) {
Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
ctor = ctors[0];
}
else {
try {
ctor = clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("No primary or default constructor found for " + clazz, ex);
}
}
}
Object attribute = constructAttribute(ctor, attributeName, parameter, binderFactory, webRequest);
if (parameter != nestedParameter) {
attribute = Optional.of(attribute);
}
return attribute;
}
在这里收先获取了参数里的对象的构造器,然后根据构造器创建除了对象,
然后返回到上一步,紧接着执行了:bindRequestParameters(binder, webRequest);来绑定参数值
bindRequestParameters(binder, webRequest);
@Override
protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
Assert.state(servletRequest != null, "No ServletRequest");
ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
servletBinder.bind(servletRequest);
}
它首先获取到了request对象以及绑定对象,最后执行了数据绑定方法:servletBinder.bind(servletRequest);****
servletBinder.bind(servletRequest);
public void bind(ServletRequest request) {
MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(request);
MultipartRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartRequest.class);
if (multipartRequest != null) {
bindMultipart(multipartRequest.getMultiFileMap(), mpvs);
}
addBindValues(mpvs, request);
doBind(mpvs);
}
protected void doBind(MutablePropertyValues mpvs) {
checkAllowedFields(mpvs);
checkRequiredFields(mpvs);
applyPropertyValues(mpvs);
}
protected void applyPropertyValues(MutablePropertyValues mpvs) {
try {
// Bind request parameters onto target object.
getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields());
}
catch (PropertyBatchUpdateException ex) {
// Use bind error processor to create FieldErrors.
for (PropertyAccessException pae : ex.getPropertyAccessExceptions()) {
getBindingErrorProcessor().processPropertyAccessException(pae, getInternalBindingResult());
}
}
}
最终执行完。完成了参数的绑定
返回数据到页面
@Controller
/*@RequestMapping("/user")*/
public class UserController {
@RequestMapping(value="/add1.do",method=RequestMethod.POST)
public String add1(HttpServletRequest request,
HttpServletResponse response,HttpSession session){
String userNum=request.getParameter("userNum");
String passWord=request.getParameter("passWord");
System.out.println("userNumber:"+userNum+" password:"+passWord);
String user="userNumber:"+userNum+" password:"+passWord;
request.setAttribute("user", user);
return "user/success";
}
@RequestMapping(value="/add2.do",method=RequestMethod.POST)
public ModelAndView add2(String usernum,String password){
ModelAndView mav=new ModelAndView("user/success");
mav.addObject("userNum",usernum);
mav.addObject("passWord", password);
return mav;
}
/*用的最多*/
@RequestMapping(value="/add3.do",method=RequestMethod.POST)
public String add3(Model model,@RequestParam(value="usernum")String usernum,Integer password){
model.addAttribute("userNum",usernum);
model.addAttribute("passWord", password);
return "user/success";
}
@RequestMapping(value="/add4.do",method=RequestMethod.POST)
public String add4(Map map,@RequestParam(value="usernum")String usernum,Integer password){
map.put("userNum",usernum);
map.put("passWord", password);
return "user/success";
}
}
处理器适配器
处理器适配器 HandlerAdapter:作用是根据映射器找到的处理器 Handler 信息,按照特定的规则去执行相关的处理器 Handler。处理完成后,返回视图ModelAndView
0x00:介绍
处理器适配器 HandlerAdapter:作用是根据映射器找到的处理器 Handler 信息,按照特定的规则去执行相关的处理器 Handler。其配置方式有两种,一种是基于 xml 的资源配置,也就是非注解的配置方式。另外一种就是基于 Annotation 注解的配置。其注解在代码中做上特殊标记,这些标记就可以编译、类加载、运行时被读取,然后去执行相应的处理。
0x01:非注解处理器适配器
2,第二个是 HttpRequestHandlerAdapter,翻译过来就是 http 请求处理器适配器,它要求编写的 Handler 需要实现 HttpRequestHandler 接口。使用这种 Handler 的开发方式,方便开发者获取 request 的相关 http 请求信息,以及设置返回对象 response 的一些参数。其配置示例如下: 然后在之前的处理器映射器配置中添加这个 Handler 的 url 映射信息,其示例代码如下: testController1 testController2 处理器映射器就是根据 url 来查找 Handler,处理器适配器就是按照它要求的规则去执行 Handler,但是一个 Handler 类中只能编写一个方法,这个弊端就可以通过注解的方式来解决。
1,第一个是 SimpleControllerHandlerAdapter,翻译过来就是简单的控制器处理器适配器,它支持所有实现了 Controller 接口的 Handler 控制器,如果开发中编写了实现 Controller 接口的控制器,则 SimpleControllerHandlerAdapter 适配器就会去执行 Controller 的具体方法。其配置示例如下:0x02:注解处理器适配器
注解处理器适配器,只需要在指定的地方声明一些注解信息即可。在 spring3.1 之后,springmvc 新的基于注解的适配器默认是 RequestMappingHandlerAdapter,它位于 springmvc 核心 jar 包 org.springframework.web.servlet.mvc.method.annotation
包下。其第一种方式是在 springmvc.xml 中声明 bean 和实现方式即可,示例代码如下:
第二种方式是使用 标签来配置,它是一种简写模式,它会自动注册处理器适配器,配置方式如下:mvc:annotation-driven</mvc:annotation-driven>
当我们使用了其注解方式后,就无需在 xml 配置中配置其它任何信息了,而只需要在作为 Handler 处理器的 Java 类中去添加相应的注解即可,示例代码框架如下://使用Controller来标识它是一个控制器
@Controller
public class TestControllerTest{
@RequestMapping("/testurl")
public ModelAndView testurl() throws Exception{
//逻辑代码
}
}
在以上代码中 @Controller 是注解信息,表示该类是一个控制器类,可以被注解的处理器适配器找到,而 TestControllerTest 类中的 testurl 方法上有一个 @RequestMapping 注解信息,作用是指定一个 url 与该方法绑定。这时为了让注解的处理器映射器能找到 Handler 控制器,需要在 springmvc.xml 做下配置,方式有两种:
1,在 springmcv.xml 中声明 bean 信息,示例代码如下:
第二种是扫描配置,对某一个包下的所有类进行扫描,找出所有使用 @Controller 注解的 Handler 控制器类,示例代码如下:<context:component-scan base-package=“com.fageweiketang.controller”></context:component-scan>
可以发现,上面这段和之前的处理器映射器一样,其配置通用。0x03:总结
SpringMVC 中处理器映射器 HandlerMapping 根据配置找到相应的 Handler,返回给前端控制器 DispatcherServlet,前端控制器再传给处理器适配器让它进行处理,处理器适配器会去找到对应的 Handler 去处理,处理后则就会返回一个 ModleAndView 对象。其配置方式有两种,一个是非注解方式配置,也就是基于 xml 配置文件。第二个就是注解配置,在类中做相应的注解即可。
————————————————
版权声明:本文为CSDN博主「aFa攻防实验室」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fageweiketang/article/details/81087852
拦截器
- xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bolife.blog.intercepter.HomeResourceInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/admin"/>
<bean class="com.bolife.blog.intercepter.SecurityInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<mvc:exclude-mapping path="/admin/logout"/>
<mvc:exclude-mapping path="/admin/comment/**"/>
<bean class="com.bolife.blog.intercepter.SecurityInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
- 拦截器代码
@Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws IOException {
User user = (User) request.getSession().getAttribute("user");
//这里可以根据session的用户来判断角色的权限,根据权限来转发不同的页面
if(user == null) {
response.sendRedirect("/login");
return false;
}
//设置登陆之后的权限
if(user != null && user.getUserStatus() != 1){
response.sendRedirect("/");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
}
}
总结:
通过写一个类继承HandlerInterceptorAdapter类,或者实现HandlerInterceptor接口,实现它的preHandle()、postHandle()、afterCompletion()方法,最后在springMVC的配置文件中进行一些配置就好了。
配置介绍:
1)mvc:mapping 拦截器路径配置
2)mvc:exclude-mapping 拦截器不需要拦截的路径
Ajax与文件上传
- 首先在xml文件中配置文件上传解析器:
<!--注册multipartResolver,由DispatcherServlet来负责调用,id的名称必须写为 multipartResolve-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置字符编码防止文件名乱码-->
<property name="defaultEncoding" value="utf-8"/>
<!--设置上传文件的总大小,单位是字节b-->
<property name="maxUploadSize" value="1048576"/>
<!--设置单个上传文件的大小,单位是字节b-->
<property name="maxUploadSizePerFile" value="1048576"/>
<!--设置内存缓冲区的大小,当超过该值的时候会写入到临时目录-->
<property name="maxInMemorySize" value="1048576"/>
<!--设置临时目录-->
<property name="uploadTempDir" value="tempupload"/>
<!--默认是false,如果设置为true的话,不会将文件路径去除,在IE浏览器下上传时会将路径名也作为文件名上传-->
<property name="preserveFilename" value="false"/>
<!--是否使用懒加载,默认是false-->
<property name="resolveLazily" value="true"/>
</bean>
- 前端:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>
</head>
<body>
<h1>文件上传</h1>
<hr>
<h3>上传图片并显示</h3>
<form>
<input id="file" type="file" name="img"><input id="image" type="button">
</form>
<div id="show">
<img id="show-img" src="">
</div>
<hr>
<h3>上传Excel并转换为Model并显示</h3>
<form>
<input type="file" name="img"><input type="submit">
</form>
<#--<div id="show">-->
<#--</div>-->
<script>
$(function () {
var pathName = window.location.pathname;
var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
var image = $("#image");
image.click(function() {
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
url:"${contextPath}/up/image",
type:"POST",
processData:false,
contentType:false,
data: formData,
success: function (result) {
$("#show-img").attr("src",projectName+"/up/file/"+result);
}
});
});
});
</script>
</body>
</html>
- 后端
@RequestMapping(value = "/up/image",method = RequestMethod.POST)
@ResponseBody
public String upImage(@RequestParam("file") MultipartFile file,Model model){
String filename =UUID.randomUUID().toString()+".jpg";
String path = "D:\\226\\images\\test\\"+ filename;
try {
String originalFilename = file.getOriginalFilename();
File file1 = new File(path);
file.transferTo(file1);
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}
contentType:false,
data: formData,
success: function (result) {
$("#show-img").attr("src",projectName+"/up/file/"+result);
}
});
});
});
```
- 后端
@RequestMapping(value = "/up/image",method = RequestMethod.POST)
@ResponseBody
public String upImage(@RequestParam("file") MultipartFile file,Model model){
String filename =UUID.randomUUID().toString()+".jpg";
String path = "D:\\226\\images\\test\\"+ filename;
try {
String originalFilename = file.getOriginalFilename();
File file1 = new File(path);
file.transferTo(file1);
} catch (Exception e) {
e.printStackTrace();
}
return filename;
}