目录结构
其实最重要的就是这个webInitialier,在里面配置好rootconfig跟sercletconfig就可以跑起来啦,只不过什么都不能干。
getSercletMappings获取默认的路径。
package com.glodon.springdemo8.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
这个是webconfig,里面的bean配置的是一个视图解析器,如果不配置上,那网页就会被直接下载下来。这配置的就是在返回的字符串上拼接上前缀跟后缀。
扫描的两个路径是前面的笔记提到的controller跟advice,当需要扫描多包时就这样扫描。
package com.glodon.springdemo8.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan({"com.glodon.springdemo8.controller","com.glodon.springdemo8.advice"})
public class WebConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
rootconfig啥都没配置不放上来了。
这样,我在pom中添加了jetty依赖,就可以把这个web程序跑起来啦。
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.5.v20170502</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<httpConnector>
<port>8080</port>
</httpConnector>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
然后继续向上添加实验:
写了一个controller:
package com.glodon.springdemo8.controller;
import com.glodon.springdemo8.exception.BadRequestException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("hello")
public class HelloController {
@GetMapping("get")
public String getMethod(){
return "hello";
}
@GetMapping("exceptions")
public String exceptions(){
throw new BadRequestException();
}
@GetMapping("exceptionHandled")
public String exceptionHandled(){
try{
throw new BadRequestException();
}catch (BadRequestException e){
return "error";
}
}
@GetMapping("redirect")
public String redirect(){
return "redirect:/hello/get";
}
}
看到可以返回简单的字符串,可以抛出异常,可以在其中做异常处理,可以重定向。
先说第一个,返回的字符串可以被解析成一个jsp页面,我就写了一个最简单的jsp页面,作为实验。成功。
第二个,可以发现我自己定义了一个异常:
package com.glodon.springdemo8.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value= HttpStatus.BAD_REQUEST,reason = "This is a bad request!")
public class BadRequestException extends RuntimeException {
}
当抛出这个异常对象的时候,浏览器会得到一个400的状态码,并且会得到上面注释的信息“This is a bad request!”
第三个,都返回至一个error页面。
第四个,重定向至链接hello/get。
之前提到,在webconfig中还进行了advice的扫描,是因为我们定义了这个:
package com.glodon.springdemo8.advice;
import com.glodon.springdemo8.exception.BadRequestException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class AllExceptionsHandler {
@ExceptionHandler(BadRequestException.class)
public String anyExceptionHandler(){
System.out.println("get a badrequest exception.");
return "error";
}
}
一个控制器切面,织入所有控制器,当任意控制器抛出BadRequestException的时候,打印一条语句并定位到error页面。
最后的一点:
package com.glodon.springdemo8.config;
import com.glodon.springdemo8.filter.LogFilter;
import org.springframework.web.WebApplicationInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
public class MyFilterInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
javax.servlet.FilterRegistration.Dynamic filter = servletContext.addFilter("logFilter", LogFilter.class);
filter.addMappingForUrlPatterns(null, false, "/hello/get");
}
}
我们可以自己配置filter,logFilter是我们自己定义的类:
package com.glodon.springdemo8.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class LogFilter implements Filter {
@Override
public void destroy() {
System.err.println("...filter destroy...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.err.println("...doFilter...");
System.out.println(request);
chain.doFilter(request, response);//要传递下一个Filter,如果没有的话,请求会一直卡住。
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.err.println("...init Filter...");
}
}
因为指定了过滤器在访问hello/get的时候才执行doFilter,所以,,嗯。