- 
                Notifications
    You must be signed in to change notification settings 
- Fork 20
SpringMVC
目录 start
目录 end|2020-05-17 16:13|
统一使用一个Servlet 进行请求的收发, 通过配置的URL对应的方法, 进行调用, 然后返回视图解析器进行渲染
- 核心类是DispatchServlet 由它来接收各种请求
- 发出request请求,到controller解析器,得到Model和view等的名字
- 发送到controller执行,返回view名字
- 发送到视图解析器
- 执行视图返回到dispatchServlet
也就是Maven的Web结构,甚至是Eclipse那样的DynamicWeb项目结构, 参考 博客
    <properties>
        <spring.version>4.3.9.RELEASE</spring.version>
    </properties>
    ......
    <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>
    <!-- 如果使用JSP作为视图层,还需 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>    compile('org.springframework:spring-web:4.3.9.RELEASE')
    compile('org.springframework:spring-webmvc:4.3.9.RELEASE')  <servlet>
    <servlet-name>mysql</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet-mapping>
    <servlet-name>mysql</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>    <?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:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                    http://www.sprinControllergframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-3.2.xsd
                http://www.springframework.org/schema/mvc
                http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--启用spring的一些annotation -->
    <context:annotation-config/>
    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
    <context:component-scan base-package="com.test.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!--HandlerMapping 无需配置,springmvc可以默认启动-->
    <!--静态资源映射-->
    <!--本项目把静态资源放在了WEB-INF的statics目录下,资源映射如下-->
    <!--<mvc:resources mapping="/css/**" location="/WEB-INF/statics/css/"/>-->
    <!--<mvc:resources mapping="/js/**" location="/WEB-INF/statics/js/"/>-->
    <!--<mvc:resources mapping="/image/**" location="/WEB-INF/statics/image/"/>-->
    <!--但是项目部署到linux下发现WEB-INF的静态资源会出现无法解析的情况,但是本地tomcat访问正常,因此建议还是直接把静态资源放在webapp的statics下,映射配置如下-->
    <!--<mvc:resources mapping="/css/**" location="/statics/css/"/>-->
    <!--<mvc:resources mapping="/js/**" location="/statics/js/"/>-->
    <!--<mvc:resources mapping="/image/**" location="/statics/images/"/>-->
    <!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
    <mvc:annotation-driven/>
    <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀(如果最后一个还是表示文件夹,则最后的斜杠不要漏了) 使用JSP-->
    <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
    <!--<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">-->
        <!--<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>-->
        <!--<property name="prefix" value="/WEB-INF/views/"/><!–设置JSP文件的目录位置–>-->
        <!--<property name="suffix" value=".jsp"/>-->
    <!--</bean>-->
    <!-- springmvc文件上传需要配置的节点-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="20971500"/>
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="resolveLazily" value="true"/>
    </bean>
    </beans>public class ExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        Map<String, Object> model = new HashMap<>();
        model.put("ex", ex);
        ex.printStackTrace();//打印异常信息
        // 根据不同错误转向不同页面
        if (ex instanceof CSRFException) {//受到csrf攻击
           return new ModelAndView("/errorPage/error", model);
        }
        if (ex instanceof BusinessException) {//业务逻辑处理出错
            return new ModelAndView("errorPage/businessError", model);
        } else if (ex instanceof ParameterException) {//参数处理出错。
            return new ModelAndView("errorPage/parameterError", model);
        } else {  //其他数据类型错误
            return new ModelAndView("errorPage/error", model);
        }
        return new ModelAndView("error", model);
    }
}
// 或者是在 Controller 层直接处理
    @ControllerAdvice
    public class ExceptionHandle{
    @EXceptionHandler({Exception.class})
    public ModelAndView dealException(Exception e){
        ModelAndView view = new ModelAndView("exception";
        Exception e = new Exception("错误信息");
        view.addObject("",e.getMessage());
        return view;
    }但如果是前后端分离的话, 就只能统一处理异常然后然后对应的错误码和提示信息了 参考博客 ResponseBody方案
    // 自定义错误页面 需要放在静态资源下面
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container -> {
            ErrorPage error401Page = new ErrorPage(HttpStatus.FORBIDDEN, "/500.html");
            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
            ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
            container.addErrorPages(error401Page, error404Page, error500Page);
        });
    }参考博客
但是奇怪的是某些方法用第二种正常,有些还是要用第一种
- 单个方法:@GetMapping(value = "/target/all", produces = "application/json; charset=utf-8")
- 或者整个应用 注意:</mvc:annotation-driven>只能有一个,要将上面的覆盖掉
 <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                    <!-- 如果是前后端使用JSON作为主要数据交换格式就把JSON列为第一个, 否则就会被认为是Text -->
                        <value>application/json; charset=UTF-8</value>
                        <value>text/plain; charset=UTF-8</value>
                        <value>text/html; charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>包 com.test.controller 下创建一个类
@RestController
@RequestMapping("/hi")
public class Hi {
    @RequestMapping("/hi")
    public String hi(){
        return "Hi";
    }
}使用上 ResponseEntity 让响应结果规范
 @RequestMapping("/handle")
 public ResponseEntity<String> handle() {
   URI location = ...;
   HttpHeaders responseHeaders = new HttpHeaders();
   responseHeaders.setLocation(location);
   responseHeaders.set("MyResponseHeader", "MyValue");
   return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
 }在Springboot框架中,static templates 文件夹下分别代表了tomcat管理的静态文件和MVC负责跳转的HTML文件或JSP文件 在static中对于路径的使用一定要带上应用路径,而在templates中就只要写相对路径即可
    <mvc:annotation-driven conversion-service="conversionService" />
    <!--配置ConversionService -->
    <bean id="conversionService"
        class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="DateConverter" />
            </set>
        </property>
    </bean>implements HandleInterceptor 有三个方法
preHandle 返回true就继续往后,false就被拦截 PostHandle 在渲染视图之前, afterCompletion 渲染视图之后调用,释放资源
    <mvc:interceptors>
        <mvc:interceptor>
            <bean class=""></bean>
            <mvc:mapping path="/**"/>
        </mvc:interceptor>
    </mvc:interceptors>定义拦截器类
public class MythInterceptor extends HandlerInterceptorAdapter{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Long startTime = System.currentTimeMillis();
        request.setAttribute("startTime",startTime);
        return true;// true就继续跳转,false就停止
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        long startTime = (Long)request.getAttribute("startTime");
        request.removeAttribute("startTime");
        Long endTime = System.currentTimeMillis();
        log.info(request.getRequestURL()+"发起请求耗时:[ "+ (endTime - startTime) +"  ms]");
    }
}配置MVC的配置类
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
    //自定义拦截器bean
    @Bean
    public MythInterceptor mythInterceptor(){
        return new MythInterceptor();
    }
    //注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截器的URL正则
        registry.addInterceptor(mythInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}URL 中带了 jsessionid 参数,导致页面各种问题
- 
一种原因:禁用cookie导致的 
- 
最终解决: chrome中在设置里清除localhost的所有cookie和缓存 
- 
【 Algorithm 】 
- 
【 Blog 】 
- 
【 C 】 
- 
【 Database 】 
- 
【 Distributed 】 
- 
【 FrontEnd 】 - 【 FrontEnd/Frame 】
- 【 FrontEnd/Node 】
- Font
- Hexo
- JavaScript
- LearnPS
- ResponseCode
- SVG
- ViewSolution
- extjs学习笔记
 
- 
【 Functional 】 
- 
【 Go 】 
- 
【 Groovy 】 
- 
【 Java 】 - 【 Java/AdvancedLearning 】
- 【 JavaBasic 】
- 【 JavaCache 】
- 【 JavaCollection 】
- 【 JavaConcurrency 】
- 【 JavaMap 】
- Annotation
- ClassFile
- Collection
- Concurrency
- Deploy
- Exception
- ExtendsAndInterface
- Generics
- IO
- JDBC
- JDKAndJRE
- JMX
- JVM
- Java11
- Java7
- Java8
- JavaNetwork
- JavaReleaseVersion
- JavaWeb
- JvmPerformance
- MQ
- MultipleLanguage
- Proxy
- Reflection
- Serialize
- SyntaxAndType
- Thread
- WebPerformance
 
- 【 Java/Android 】
- 【 Java/Ecosystem 】
- 【 Java/MSA 】
- 【 Java/Spring 】
- 【 Java/TemplateEngine 】
- 【 Java/Test 】
- 【 Java/Tool 】
- 【 Java/thread 】
- AlibabaJavaStandard
- DesignPattern
- HashMap解析
- Java-NIO
- Java虚拟机
- Log
- MIS
- Quartz
- RESTful
- WebSocket学习笔记
- ZooKeeper学习笔记
- android学习笔记
 
- 【 Java/AdvancedLearning 】
- 
【 Kotlin 】 
- 
【 Linux 】 - 【 Linux/Alpine 】
- 【 Linux/Arch 】
- 【 Linux/Base 】
- 【 Linux/Centos 】
- 【 Linux/Container 】
- 【 Linux/Debian 】
- 【 Linux/Tool 】
- JavaDevInit
- Linux系统学习
 
- 
【 MyBlog 】 
- 
【 Python 】 - 【 Python/Tool 】
- Python
- PythonConcurrent
- PythonGUI
- PythonGame
- PythonNet
- PythonOffices
- PythonWeb
- Python基础
- Python核心学习
 
- 
【 Reactive 】 
- 
【 Rust 】 
- 
【 Scala 】 
- 
【 Script 】 
- 
【 Skills 】 - 【 Skills/Application 】
- 【 Skills/CS 】
- 【 Skills/Cache 】
- 【 Skills/Councurrency 】
- 【 Skills/DevOps 】
- 【 Skills/Document 】
- 【 Skills/Ecology 】
- 【 Skills/Network 】
- 【 Skills/Search 】
- 【 Skills/SoftwareEngineering 】
- 【 Skills/Spider 】
- 【 Skills/Test 】
- 【 Skills/Vcs 】
- 【 Skills/Work 】
- AppManual
- CelebrityQuotes
- Miscellaneous
- Platform
- Problem
- Protobuf
- RegularExpression
- SoftwareDesignEngineer
- Website
 
- 
【 Windows 】 
