spring MVC 学习

spring MVC 学习

首先来个hello world例子。

我们在index.jsp中弄一个超链接

<a href="helloworld">helloworld</a>

新建个handler,用来处理请求的url,这里我们使用注解的方式来映射url。


@Controller
public class HelloWorld {


    /**
     * 使用  RequestMapping 来映射请求的 url。
     * 返回值会通过视图解析器来解析为实际的视图。通过 prefix + returnValue + 后缀  得到路径,任何使用转发.
     * @return
     */
    @RequestMapping("/helloworld")
    private String hello() {

        System.out.println("hellow world...................");

        return "success";
    }
}

在spingmvc.xml中我们要配置

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="com.mamh.springmvc.demo.handlers"/>


    <!-- 配置视图解析器,如何把hanlder方法返回值解析为物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

web.xml文件的配置



<web-app>


    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


</web-app>

整个工程使用maven来管理,其中pom文件


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>mamh</groupId>
    <artifactId>spring</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>spring Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.0.4.RELEASE</spring.version>
    </properties>


    <dependencies>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>

        <!--j2ee相关包 servlet、jsp、jstl-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </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>

        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <!--spring相关包, 在web中需要使用spring-web和spring-webmvc这2个jar包的-->
        <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>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.13</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.15.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.2.15.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.9.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.7</version>
        </dependency>

        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>12.2.0.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.2.15.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.5.16</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin -->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-spring-plugin</artifactId>
            <version>2.5</version>
        </dependency>


    </dependencies>

    <build>
        <finalName>spring</finalName>

        <resources>
            <!--表示把java目录下的有关xml文件,properties文件编译/打包的时候放在resource目录下-->
            <resource>
                <directory>${basedir}/src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <!--servlet容器 jetty插件-->
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.3.10.v20160621</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

@RequestMapping(“/helloworld”)详解

这个注解也能加到class上。如果同时class上和method都加的有,那url的映射是2个加到一起的。

类上没有就是相对于web应用的根目录的。方法出的相对于类定义处的。


@RequestMapping("/class")
@Controller
public class HelloWorld {


    /**
     * 使用  RequestMapping 来映射请求的 url。
     * 返回值会通过视图解析器来解析为实际的视图。通过 prefix + returnValue + 后缀  得到路径,任何使用转发.
     * @return
     */
    @RequestMapping("/helloworld")
    private String hello() {

        System.out.println("hellow world...................");

        return "success";
    }
}

这样类上加了@RequestMapping(“/class”) 之后 的url就是这样http://localhost:8080/class/helloworld来访问了。

先前的没有加的是http://localhost:8080/helloworld来访问了

@RequestMapping()请求方式,value,method属性

@RequestMapping 的 value、method、params 及 heads
分别表示请求 URL、请求方法、请求参数及请求头的映射条
件,他们之间是与的关系,联合使用多个条件可让请求映射
更加精确化。

常用的method的两个值:
RequestMethod.POST ,RequestMethod.GET


    @RequestMapping(value = "/testMethod", method = RequestMethod.POST)
    private String testMethod() {
        System.out.println("hellow world....testMethod...............");


        return "success";

    }

@RequestMapping()请求参数,请求头

params 和 headers支持简单的表达式:

param1: 表示请求必须包含名为 param1 的请求参数 –
!param1: 表示请求不能包含名为 param1 的请求参数 –
param1 != value1: 表示请求包含名为 param1 的请求参数,但其– 值不能为 value1
{“param1=value1”, “param2”}: 请求必须包含名为 param1param2 –的两个请求参数,且 param1 参数的值必须为 value1


    @RequestMapping(value = "/testParams", params = {"username", "age!=10"})
    private String testParams() {
        System.out.println("hellow world....testParams...............");


        return "success";

    }

http://localhost:8080/testParams?username=mamh&age=101这个就能访问,age改为10就不行了。


    @RequestMapping(value = "/testParams", 
    params = {"username", "age!=10"},
    headers = {"Accept-Language=zh-CN,en-US;q=0.7,en;q=0.3"})
    private String testParams() {
        System.out.println("hellow world....testParams...............");
        return "success";
    }

@RequestMapping()支持 ant风格统配匹配

Ant 风格资源地址支持 3 种匹配符:

?:匹配文件名中的一个字符 –   
*:匹配文件名中的任意字符 –   
 **:** 匹配多层路径   

@RequestMapping 还支持 Ant 风格的 URL :

/user/*/createUser: 匹配  
/user/aaa/createUser、/user/bbb/createUser 等 URL

/user/**/createUser: 匹配  
/user/createUser、/user/aaa/bbb/createUser 等 URL

/user/createUser??: 匹配  
/user/createUseraa、/user/createUserbb 等 URL


    @RequestMapping(value = "/testPath/*/abc")
    private String testPath() {
        System.out.println("hellow world....testPath...............");
        return "success";
    }

http://localhost:8080/testPath/a/abc可以。
http://localhost:8080/testPath/b/abc也可以匹配

@PathVariable 映射 URL 绑定的占位符



    @RequestMapping(value = "/testPathVariable{id}")
    private String testPathVariable(@PathVariable(value = "id") int id) {
        System.out.println("hellow world....PathVariable............... id = " + id);
        return "success";
    }

访问这样http://localhost:8080/testPathVariable2323访问,会得到参数id是2323.
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过
@PathVariable(“xxx”) 绑定到操作方法的入参中。

REST:即 Representational State Transfer。(资源)表现层状态转化。


REST:即 Representational State Transfer。(资源)表现层状态转化。是目前 •
最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,
所以正得到越来越多网站的采用
资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它 •
可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。
可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要
获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识
别符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层 •
(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格
式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
状态转化(State Transfer):每• 发出一个请求,就代表了客户端和服务器的一
次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器
端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“
状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “
表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动
词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获
取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

form表单是不支持delete,和put的,不过我们可以添加一个隐藏域使用post方式转换到delete或put




<form action="springmvc/testREST/1" method="post">
    <input type="hidden" name="_method" value="PUT"/>
    <input type="submit" value="TestRest PUT"/>
</form>
<br><br>

<form action="springmvc/testREST/1" method="post">
    <input type="hidden" name="_method" value="DELETE"/>
    <input type="submit" value="TestRest DELETE"/>
</form>
<br><br>

<form action="springmvc/testREST" method="post">
    <input type="submit" value="TestRest POST"/>
</form>
<br><br>

<a href="springmvc/testREST/1">Test Rest Get</a>
<br><br>


    @RequestMapping(value = "/testREST/{id}", method = RequestMethod.GET)
    private String testGET(@PathVariable(value = "id") int id) {
        System.out.println("testREST  GET : " + id);
        return "success";
    }

    @RequestMapping(value = "/testREST/{id}", method = RequestMethod.PUT)
    private String testPUT(@PathVariable(value = "id") int id) {
        System.out.println("testREST  PUT : " + id);
        return "success";
    }

    @RequestMapping(value = "/testREST/{id}", method = RequestMethod.DELETE)
    private String testDELETE(@PathVariable(value = "id") int id) {
        System.out.println("testREST  DELETE : " + id);
        return "success";
    }

    @RequestMapping(value = "/testREST", method = RequestMethod.POST)
    private String testPOST() {
        System.out.println("testREST   POST : ");
        return "success";
    }

这里使用HiddenHttpMethodFilter过滤器来把post请求转换为delete或put请求,



    <filter>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

从java中的代码我们可以看到 需要 在post请求中传过滤的参数是DEFAULT_METHOD_PARAM = “_method”

public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method";

    public HiddenHttpMethodFilter() {
    }

    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
            String paramValue = request.getParameter(this.methodParam);
            if (StringUtils.hasLength(paramValue)) {
                requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, paramValue);
            }
        }

        filterChain.doFilter((ServletRequest)requestToUse, response);
    }

    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
        private final String method;

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
            super(request);
            this.method = method.toUpperCase(Locale.ENGLISH);
        }

        public String getMethod() {
            return this.method;
        }
    }
}

@RequestParam 映射请求参数
value值就是请求参数值
required决定这个请求参数是否是必须的
defaultValue可以给这个请求参数设置个默认值


    @RequestMapping("/testRequestParam")
    private String testRequestParam(@RequestParam(value = "username") String username,
                                    @RequestParam(value = "password") String password) {
        System.out.println("hellow world....testRequestParam..............username = " + username + "  password = " + password);

        return "success";
    }

http://localhost:8080/springmvc/testRequestParam?username=123&password=abc
访问的时候如果没带请求参数是会报错的。 可以加上required = false来设置是否需要,还可以设置个defaultValue。

@RequestHeader 绑定请求报头的属性值

    @RequestMapping("/testRequestHeader")
    private String testRequestHeader(@RequestHeader(value = "Accept-Language") String al) {
        System.out.println("hellow world.....testRequestHeader............\"Accept-Language\" = " + al);
        return "success";
    }

http://localhost:8080/springmvc/testRequestHeader

@CookieValue 绑定请求中的 Cookie 值


    @RequestMapping("/testCookieValue")
    private String testCookieValue(@CookieValue(value = "JSESSIONID") String c) {
        System.out.println("hellow world.....testCookieValue....CookieValue =  " + c);
        return "success";
    }

使用 POJO 对象绑定请求参数值
Spring MVC 会按• 请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
如:dept.deptId、dept.address.tel 等

    @RequestMapping("/testPOJO")
    private String testPOJO(User user) {
        System.out.println("hellow world.....testPOJO..." + user);
        return "success";
    }

使用 Servlet API 原生API


HttpServletRequest  
HttpServletResponse  
HttpSession  
java.security.Principal  
Locale  
InputStream  
OutputStream 
Reader  
Writer

@SessionAttributes

若希望在多个请求之间共用某个模型属性数据,则可以在 控制器类上标注一个 @SessionAttributes, Spring MVC 将在模型中对应的属性暂存到 HttpSession 中。

@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中


@SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。

@SessionAttributes(value={“user1”, “user2”}) 

@SessionAttributes(types={User.class, Dept.class}) 

@SessionAttributes(value={“user1”, “user2”}, types={Dept.class})


    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Map<String, Object> map) {
        User user = new User();
        user.setAge(123);
        user.setUsername("Tom");
        user.setEmail("[email protected]");
        user.setPassword("123456");
        map.put("user", user);
        //默认这个是放到request里面的

        //可以在类上加上 @SessionAttributes(value = {"user"}, types = {Integer.class,String.class, User.class})
        //来把map中对应的类型的,或者对应键值的 对象也放到session中取
        map.put("string1", "xxxxxxxxxxxxxxxxxxx this is a stirng ....");
        map.put("int1", 123321);

        return "success";
    }

@ModelAttribute

在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。

在方法的入参前使用@ModelAttribute 注解可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参.将方法入参对象添加到模型中.


    @ModelAttribute
    public void getUser(@RequestParam(value = "id", required = false) Integer id, Map<String, Object> map) {
        if (id != null) {
            User user = new User(1, "tom", "123456", "[email protected]", 12, null);

            System.out.println("从数据库获取一个对象" + user);
            map.put("user", user);
        }
    }

    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(User user) {
        System.out.println("testModelAttribute=== " + user);


        return "success";
    }

@ModelAttribute注解,可以修身目标方法POJO入参。 当那个键不是类名第一个字母小写的时候,我们可以用
@ModelAttribute注解修饰入参,里面value就是自定义的那个键名 。例如下面我们把键名改为了“abc”,
在testModelAttribute(User user)方法中如果不使用注解那个user就是一个新建的,而不是从map中获得的。


    @ModelAttribute
    public void getUser(@RequestParam(value = "id", required = false) Integer id, Map<String, Object> map) {
        if (id != null) {
            User user = new User(1, "tom", "123456", "[email protected]", 12, null);

            System.out.println("从数据库获取一个对象" + user);
            map.put("abc", user);
        }
    }

    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(@ModelAttribute(value = "abc") User user) {
        System.out.println("testModelAttribute=== " + user);


        return "success";
    }

国际化

使用i18n国际化的时候,需要建2个properties文件
new file: src/main/resources/i18n_en_US.properties
new file: src/main/resources/i18n_zh_CN.properties

i18n.username=username
i18n.passowrd=password


i18n.username=\u7528\u6237\u540D
i18n.passowrd=\u7528\u6237\u540D

properties文件中要使用编码后的,也就是中文要变成\u 开头这样的。


    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="i18n"/>
    </bean>

view-controller


    <!-- 配置直接转发的页面,可以直接配置转发的页面,而不需要经过handler方法 -->
    <mvc:view-controller path="/success" view-name="success"/>

可以直接访问 http://localhost:8080/success了。

这个时候那个 @RequestMapping() 配置的那个返回的view就会报404错误了。这个时候可以加上
annotation-driven

    <mvc:annotation-driven/>

自定义View

    <context:component-scan base-package="com.mamh.springmvc.demo.views"/>

    <!-- 配置视图解析器 -->
    <bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <property name="order" value="100"/>
    </bean>

package com.mamh.springmvc.demo.views;

import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.View;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

@Component
public class HelloView implements View {
    @Override
    public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
                       HttpServletResponse response) throws Exception {
        response.getWriter().println("hello view, time: " + new Date());

    }

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

CRUD操作


@Controller
public class EmployeeHandler {

    @Autowired
    private EmployeeDao employeeDao;

    @Autowired
    private DepartmentDao departmentDao;

    @RequestMapping(value = "/emp", method = RequestMethod.GET)
    public String input( Map<String, Object> map) {
        System.out.println("input..........");
        map.put("departments", departmentDao.getDepartments());
        map.put("employee",new Employee());

        return "input";
    }

    @RequestMapping("/emps")
    public String list(Map<String, Object> map) {

        map.put("employees", employeeDao.getAll());

        return "list";
    }

}


<c:if test="${empty requestScope.employees}">
    没有任何信息
</c:if>
<c:if test="${!empty requestScope.employees}">
    <table border="1" cellpadding="10" cellspacing="0">
        <tr>
            <th>ID</th>
            <th>LastName</th>
            <th>Email</th>
            <th>Gender</th>
            <th>Department</th>
            <th>Edit</th>
            <th>Delete</th>
        </tr>
        <c:forEach items="${requestScope.employees}" var="emp">
            <tr>
                <td>${emp.id}</td>
                <td>${emp.lastName}</td>
                <td>${emp.email}</td>
                <td>${emp.gender == 0? 'Female': 'Male'}</td>
                <td>${emp.department.departmentName}</td>
                <td><a href="">Edit</a></td>
                <td><a href="">Delete</a></td>
            </tr>
        </c:forEach>

    </table>
</c:if>

<br/>
<a href="/emp">Add new Employee.........</a>



<!--
可以更快速的开发出表单页面,方便表单值回显

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute

可以通过 modelAttribute 属性指定绑定的模型属性,
若没有指定该属性,则默认从 request 域对象中读取
command 的表单 bean,如果该属性值也不存在,则会
发生错误。

-->

<form:form action="/emp" method="POST" modelAttribute="employee">
    LastName: <form:input path="lastName"/> <br/>

    Email: <form:input path="email"/> <br/>

    <%
        Map<String, String> genders = new HashMap();
        genders.put("1", "Male");
        genders.put("0", "Female");
        request.setAttribute("genders", genders);
    %>
    Gender: <form:radiobuttons path="gender" items="${genders}"/> <br/>

    Department: <form:select path="department" items="${departments}" itemLabel="departmentName" itemValue="id"/> <br/>


    <input type="submit" value="submit"/>
</form:form>

注意在使用<form:form>标签的时候,modelAttribute=”employee”设置的值要和放到map中的键一致。
<form:input>标签中的path对应html中的name属性,支持级联属性。

删除操作


    @RequestMapping(value = "/emp/{id}", method = RequestMethod.DELETE)
    public String delete(@PathVariable(value = "id") Integer id) {
        System.out.println("delete.........." + id);
        employeeDao.delete(id);
        return "redirect:/emps";
    }

注意spingmvc对静态资源的过滤,可以加上


    <mvc:default-servlet-handler/>

猜你喜欢

转载自blog.csdn.net/mmh19891113/article/details/80237589