SpringMVC初学者笔记

1.SpringMVC的入门:
  1)导入Spring的JAR包+SpringWeb和MVC的jar包
  2)在web.xml中配置DispatcherServlet这个转发控制器
   <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!-- 告诉SpringMVC的配置文件在什么地方 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!-- 启动即加载(值越小就优先加载)  -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 配置映射 (不要和struts的映射混淆,struts配置为/*)  -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  3)编写控制器
 public class HelloAction implements Controller {


public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {

ModelAndView modelAndView = new ModelAndView();
//放入Model里面的数据SpringMVC会自动的把它放入请求域
modelAndView.addObject("msg", "这是我的第一个Spring MVC的例子");
modelAndView.setViewName("/jsp/success.jsp");

return modelAndView;
}
}
  4)编写SpringMVC的配置文件(这个配置文件除了文件名称和Spring有点不一样,其他的配置信息都是和Spring一样的)
     在配置文件中需要配置自己编写的Controller的请求路径和类
    <bean name="/hello.action" class="com.hwadee.controller.HelloAction"></bean>(SpringIoC容器会自动去创建这个类的对象)
这个name原来是用来在ApplicationContext用getBean来获取的,限制是可以通过浏览器在地址栏中输入这个地址进行访问(可以理解为就是你的URL地址)
  5)在SpringMVC的配置文件中配置视图解析器
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>  
 
2.SpringMVC的注解配置
  1)第1和第2步和前面一样
  2)在编写Controller类,需要在类上添加@Controller(注意不能换为其他3种的一种)
      并在控制器类中不需要实现任何接口,编写你需要处理的方法信息,并在方法上添加注解@RequestMapping("/helloworld")
 然后在方法中返回你的视图的名字(注意不要加任何前缀和后缀)
 @RequestMapping("/helloworld")
public String hello() {
System.out.println("hello world");
//注意不要加任何前缀和后缀
return "success";
}
   3)配置SpringMVC的配置文件
      1.
     <!-- 配置自定扫描的包 (已识别控制器)-->
    <context:component-scan base-package="com.hwadee.springmvc"></context:component-scan>
 2.添加视图解析器
 <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property> (前缀)
<property name="suffix" value=".jsp"></property>             (后缀)
</bean>
  
3.@RequestMapping 这个注解主要是用来注解URL地址请求映射的,它可以再方法和类上使用。
   如果在类上进行配置,则代表方法本类下的方法映射时需要加上类的地址。
    /**
* 常用: 使用 method 属性来指定请求方式
*/
  @RequestMapping(value = "/testMethod", method = RequestMethod.POST)
  
    /**
* 了解: 可以使用 params 和 headers 来更加精确的映射请求. params 和 headers 支持简单的表达式.

* @return
*/
   @RequestMapping(value = "/testParamsAndHeaders", params = { "username",
"age!=10" }, headers = { "Accept-Language=en-US,zh;q=0.8" })

   /**
   * Spring 支持Ant风格
   */
@RequestMapping("/testAntPath/*/abc")

/**
* @PathVariable 可以来映射 URL 中的占位符到目标方法的参数中.
* @param id
* @return
*/
@RequestMapping(value = "/testRest/{id}/{name}", method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id,@PathVariable("name") String na) {
System.out.println("testRest Put: " + id);
return SUCCESS;
}


/**
* Rest 风格的 URL. 
* 以 CRUD 为例: 
* 新增: /order    POST 
* 修改: /order/1  PUT update?id=1 
* 获取: /order/1  GET get?id=1
* 删除: /order/1  DELETE delete?id=1

* 如何发送 PUT 请求和 DELETE 请求呢 ? 
* 1. 需要配置 HiddenHttpMethodFilter 
* 2. 需要发送 POST 请求
* 3. 需要在发送 POST 请求时携带一个 name="_method" 的隐藏域, 值为 DELETE 或 PUT
*   在 SpringMVC 的目标方法中如何得到 id 呢? 使用 @PathVariable 注解

*/
@RequestMapping(value = "/testRest/{id}/{name}", method = RequestMethod.PUT)
  
  
   控制器绑定参数和Header已经cookie信息


/**
* 了解:

* @CookieValue: 映射一个 Cookie 值. 属性同 @RequestParam
*/
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
System.out.println("testCookieValue: sessionId: " + sessionId);
return SUCCESS;
}


/**
* 了解: 映射请求头信息 用法同 @RequestParam
*/
@RequestMapping("/testRequestHeader")
public String testRequestHeader(
@RequestHeader(value = "Accept-Language") String al) {
System.out.println("testRequestHeader, Accept-Language: " + al);
return SUCCESS;
}


/**
* @RequestParam 来映射请求参数. value 值即请求参数的参数名 required 该参数是否必须. 默认为 true
*               defaultValue 请求参数的默认值
*/
@RequestMapping(value = "/testRequestParam")
public String testRequestParam(
@RequestParam(value = "username") String un,
@RequestParam(value = "age", required = false, defaultValue = "0") int age) 
{
System.out.println("testRequestParam, username: " + un + ", age: "
+ age);
return SUCCESS;
}


【注意:】
//Struts的工作是靠类来进行的,所有不能进行单例设计(因为所有属性放在类中的)
//SpringMVC它的工作方式是靠方法进行的,参数是通过方法的参数进行注入的(所有SpringMVC的控制器是可以使单例的)
  获取表单的提交信息:(自动封装为对象)
    /**
* Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配, 自动为该对象填充属性值。
* 支持级联属性。
* 如:dept.deptId、dept.address.tel 等
*/
  可以获取原生的Servlet
   /**
* 可以使用 Serlvet 原生的 API 作为目标方法的参数 具体支持以下类型

* HttpServletRequest 
* HttpServletResponse 
* HttpSession
* java.security.Principal 
* Locale InputStream 
* OutputStream 
* Reader 
* Writer
* @throws IOException 
*/
ModelAndView:是由2个部分组成(Model 和View)Mode:是一个Map结构往这个Model的Map结构中放入的数据时默认放到RequestScope中  
  /**
* 目标方法的返回值可以是 ModelAndView 类型。 
* 其中可以包含视图和模型信息
* SpringMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中. 
* @return
*/
我们可以再方法的参数中写上一个普通的Map变量,这个时候SpringMVC会自动把这个map结构当成一个Model
  
  /**
* 目标方法可以添加 Map 类型(实际上也可以是 Model 类型或 ModelMap 类型)的参数. 
* @param map
* @return
*/
 
   我们可以再Controller类的上面配置@SessionAttributes注解,表示在本类下的所有请求方法,我们可以配置在这个请求方法中如果出现放入请求域的数据Key和
@sesionAttribute的一样,则Springmvc会顺便放入Session域中
   例如:
   @SessionAttributes(value={"user"}, types={String.class})
   好处:可以再方法中不用写上原生ServletApI对象
   坏处:不够清晰,只要本类中的方法出现Rquest域中的key和我SessionAttribute一样就会存入Session。
   
@ModelAttribute:可以修饰某个方法和某个请求方法的参数。
  1)如果是修饰的某个方法,则表示方法会在每个请求方法执行前先执行一次,所以我们会在方法中判断一下是否带有特定的参数(来判断是否需要修改)
  2) 如果修饰的是某个请求方法的参数(则表示该方法的参数一定要先去@ModelAttribute所修饰的方法里面放入的Map先取一次,是按照方法的参数配置名称找的)
    @ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id, 
Map<String, Object> map){
System.out.println("modelAttribute method");
if(id != null){
//模拟从数据库中获取对象
User user = new User(1, "张三", "123456", "tom@hwadee.com", 12);
System.out.println("从数据库中获取一个对象: " + user);
map.put("user", user); //这个名字要和下面的@ModelAttribute("user")名一样
}
}

public String testModelAttribute(@ModelAttribute("user")User user){

System.out.println("修改: " + user);
return SUCCESS;
}
  
自定义视图:
  1) 编写一个类并实现View接口,实现接口中的方法:类型和渲染
  @Component("hview")
  public class HelloView implements View{


@Override
public String getContentType() {
return "text/html";
}


@Override
public void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.getWriter().print("hello view, time: " + new Date());
}
  }
  2)在springmvc 的配置文件中,配置根据BeanName来解析视图:
   <!-- 配置视图  BeanNameViewResolver 解析器: 使用视图的名字来解析视图 -->
<!-- 通过 order 属性来定义视图解析器的优先级, order 值越小优先级越高 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
【注意:】如果一个配置文件中有多个视图解析器,需要确定视图解析器的顺序,默认情况InternalResourceViewResolver放在最前面的
如果你返回的视图名在默认的视图解析找不到的情况下会交由Beanname视图解析器。

SpringMVC的重定向:
  1)重定向到其他资源:例如:redirect:http://www.baidu.com
  2)重定向到内部网站资源:
     1.:重定向到某个Jsp文件:例如:redirect:/index.jsp(这个一定要写完整,第二不能重定向到WEB-INF里面的资源,第三记得加上后缀名)
2.:重定向到某个控制器的requestMapping:redirect:/testController/testView (记得不要后缀,而且记得把类的requestmapping 加上)
   【重定向和WEB的重定向是一样的,不能共用request请求域】

SpringMVC的请求转发:
    "forward:/testRedirect";【 请求转发会共用request请求域】

SpringMVC的view——Controller配置:可以不用写Controller类,而直接写一个资源路径和视图名的映射关系。
  【注意:】要记得把InternalResourceViewResolver加入
  <mvc:view-controller path="/" view-name="success"/>
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
  </bean>

静态资源映射:
    <!-- 静态资源的映射 -->
    <!-- 表示请求地址是/stat/结尾的任意路径信息,会在/WEB-INF/static/进行处理 -->
    <mvc:resources location="/WEB-INF/static/" mapping="/stat/**"/>
    <!-- 表示如果视图解析器解析不成功时,交个Servlet容器进行处理,tomcat 里面有一个Servlet叫default  -->
    <mvc:default-servlet-handler/>

后续:
   1)文件的上传和下载
   2) 类型转换和验证
   3)拦截器
   
SpringMVC类型转换:
   1) 编写一个类实现Converter接口,并重写convert方法
     @Component
public class EmployeeConverter implements Converter<String, Employee> {


@Override
public Employee convert(String source) {
if(source != null){
String [] vals = source.split("-");
//张三-zhangsan@hwadee.com-0
if(vals != null && vals.length == 3){
String lastName = vals[0];
String email = vals[1];
Integer gender = Integer.parseInt(vals[2]);

Employee employee = new Employee();
employee.setLastName(lastName);
employee.setEmail(email);
employee.setGender(gender);
System.out.println(source + "--convert--" + employee);
return employee;
}
}
return null;
}
}
2)在SpringMVC配置文件中配置转换器:org.springframework.context.support.ConversionServiceFactoryBean
<!-- 在注解驱动中引用 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

<!-- 配置 ConversionService -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConverter"/>
</set>
</property>
</bean>

SpringMVC类型格式化:
    1)主要是针对用户输入的日期或数字字符串转换为Java的日期对象或数字类型。
2)在需要格式化对象的属性中加入注解:
  @DateTimeFormat(pattern="yyyy-MM-dd")
  @NumberFormat(pattern="#,###,###.#")
3)如果转换错误:则可以在方法中使用带参数的 BindingResult result,然后可以打印出来
  if(result.getErrorCount() > 0){
System.out.println("出错了!");

for(FieldError error:result.getFieldErrors()){
System.out.println(error.getField() + ":" + error.getDefaultMessage());
}

//若验证出错, 则转向定制的页面
return "input";
}
SpringMVC校验器:采用JSR303 ,JSR303是一个接口,我们需要使用JSR303的实现类,Hibernate validator
1). 使用 JSR 303 验证标准
2). 加入 hibernate validator 验证框架的 jar 包
3). 在 SpringMVC 配置文件中添加 <mvc:annotation-driven />
4). 需要在 bean 的属性上添加对应的注解
5). 在目标方法 bean 类型的前面添加 @Valid 注解

常用注解:
 @Null           必须为空
 @NotNull  必须不为空
 @AssertTrue     必须为true
 @AssertFalse    必须为false
 @Min            必须大于指定值
 @Max            必须小于指定值
 @Past            必须是过去的时间
 @Future          必须是将来时间
 @Email           必须是电子邮箱
 @Length          必须在指定长度
 @Range           必须在指定范围
 
错误消息国际化:  编写国际化文件,其中的Key为你的注解类名.方法参数属性名.校验属性名
例如:NotEmpty.employee.lastName=^^LastName\u4E0D\u80FD\u4E3A\u7A7A.
在SpringMVC配置文件中注册国际化资源:
<!-- 配置国际化资源文件 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>

<!-- 配置 SessionLocalResolver -->
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

 
 
SpringMVC 的文件上传:
    1)加入commons-fileupload-1.2.1.jar,commons-io-2.0.jar
2)在SpringMVC配置文件中配置MultipartResolver

<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
 
SpringMVC返回JSON:
    1) 添加包 JackSon包
jackson-mapper-asl-*.jar
jackson-core-asl-*.jar
jackson-databind-*.jar
    2)在请求方法上添加注解 @ResponseBody
例如: 
  @ResponseBody
@RequestMapping("/testJson")
public Collection<Employee> testJson(){
Map<Integer, Employee>  employees = new HashMap<Integer, Employee>();


employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));
employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));
employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));
employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));
employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));

return employees.values();
}
 
 
SpringMVC拦截器:
    1)实现HandlerInterceptor接口就可以实现拦截器
2)在SpringMVC配置中配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/lg" />
<mvc:exclude-mapping path="/loginact" />
<mvc:exclude-mapping path="/static/**" />
<bean class="org.lzjtdx.Interceptor.UserInterceptor"></bean>
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>


Spring+SpringMVC+Hibernate 配置:
 1)加入这三者的jar包(以及其他依赖包),包括常用工具包(JSON,POI,JSR303)
 2)这里的SpringMVC的配置分了2个文件(已过是Spring配置文件一个是SpringMVC的配置)
 
 【注意】:
   1.)我们的Spring和SpringMVC是单独配置的,并且在单独的配置文件中都使用了一个context:component-scan 配置
   2.)在前面学习SpringMVc的时候,我们也使用Spring的注解,并且也做到自动注入的,说明Spring和SpringMVC内部都有一个IOC容器,而且这两者是可以共用的。
   3)如果都是配置的基础包,则会扫描2次,在各自的IOC容器里面会都存在。(解决办法:是各自的IOC容器自己单独扫描)
    Spring:
 <!-- 扫描注解Bean 4個註解  -->
    <context:component-scan base-package="org.**.service,org.**.dao">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

SpringMVC:
<!-- 开启controller注解支持 -->
<context:component-scan base-package="org.**.controller">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值