栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring学习

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring学习

文章目录
    • Spring MVC获取请求参数的值
    • Spring MVC的文件上传
    • Spring MVC中JdbcTemplate的操作
    • Spring练习

Spring MVC获取请求参数的值

Spring获取请求参数的值,而请求参数的类型可以是基本的数据类型,也可以是数组,也可以是一个POJO对象,也可以是一个集合。

所以对于不同类型的参数,我们由不一样的方式进行获取:

  • 请求参数是一个基本类型/数组,那么我们只需要保证方法参数和url中的请求参数的名字相同,那么就可以进行一一映射了,例如,url为localhost:8080/test1?username=zhangshan&age=20,而方法test1的参数的名字必须要和和url中的请求参数名字相同,即test1(String username,int age),这样,这个方法中的参数的值username=zhangshan,age=20.

    但是如果希望方法中的参数名字和url中的请求参数的名字不相同,那么这时候我们需要使用注解@RequestParam(value=xxx),这样xxx就会和url中请求参数名字为xxx的参数匹配。所以上面的test1方法可以改为test1(@RequestParam(“username”)String name,@RequestParam(“age”)int age),这样也可以实现我们目的。同理,如果请求参数是一个数组,即url为localhost:8080/test2?strs=aaa&strs=bbb&strs=ccc,这时候strs就是一个数组,然后我们对应的方法需要获取这个请求参数的值的时候,我们可以将方法参数名字也取为strs,也可以利用@RequestParam(“strs”)来实现映射,从而使得方法参数的值等于请求参数的值。对应的代码为:

    @Controller
    public class Controller3 {
        
        @RequestMapping("/test1")
        @ResponseBody
        public void test1(String username,int age){
            System.out.println("username = " + username + ", age = " + age);
        }
    
        
        @RequestMapping("/test3")
        @ResponseBody
        public void test3(String[] strs){
            System.out.println(Arrays.asList(strs));//Arrays.asList,将数组转成List,然后输出
        }
    
        
        @RequestMapping("/test6")
        @ResponseBody
        public void test6(@RequestParam("username")String name, @RequestParam(value="age",defaultValue="20")int age){
            System.out.println("username = " + name + ", age = " + age);
        }
    
        @RequestMapping("/test9")
        @ResponseBody
        public void test9(@RequestParam("strs")String[] strings){
            System.out.println(Arrays.asList(strings));
        }
    
    }
    
  • 如果方法的参数是一个对象,例如User的时候,也即我们希望将url中的请求参数封装到一个对象中,那么这时候我们只需要将对象User中的属性成员的名字和请求参数的名字相同,并且这个对象含有get/set方法,这样我们就可以将请求参数的值封装到一个对象中。对应代码如下所示:

  • 如果请求的参数是一个集合,那么这时候我们可以有2种方式解决:

    1. 采用方法参数是一个对象的的形式,我们只需要保证这个对象中含有和请求参数名字相同的集合属性,以及含有set/get方法即可,对应的代码为:

      @RequestMapping("/test4")
      @ResponseBody
      public void test4(Vo vo){
          System.out.println(vo);
      }
      
      //Vo类
      public class Vo {
          private List list;
      
          public void setList(List list) {
              this.list = list;
          }
      
          public List getList() {
              return list;
          }
      
          @Override
          public String toString() {
              return "Vo{" +
                      "list=" + list +
                      '}';
          }
      }
      
      

      对应的user.jsp代码:

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      
      
          获取表单中的多个user
      
      
          
      姓名 年龄

      但是如果我们输入的数据中含有中文的时候,那么这时候,就会发现后台数据是发生了乱码,这时候我们需要解决的是全局的乱码问题,而要解决全局乱码问题,可以通过spring mvc的CharacterEncodingFilter来解决,不过我们需要在web.xml中配置这个过滤器,只要将下面的代码添加到web.xml中即可:

      
          CharacterEncodingFilter
          org.springframework.web.filter.CharacterEncodingFilter
          
              encoding
              utf-8
          
      
      
          CharacterEncodingFilter
          
          System.out.println(userList);
      }
      

      正常情况下,运行的时候,会因为没有找到jquery-3.3.1.js文件,从而导致ajax.jsp中的$is not defined。原因是Spring MVC没有办法找到静态资源js/jquery-3.3.1.js,所以为了解决这个问题,我们需要在spring-mvc中进行配置。但是Spring Boot中已经默认帮我们配置了,所以上面的代码是可以正常运行的。

      但是如果我们需要导入静态资源,那么需要在spring-mvc中通过添加下面的任意一行代码到spring-mvc.xml中即可:

      
      
          System.out.println(username);
      }
      

在上面的案例test1中,对应的代码为:

@ResponseBody
public void test1(String username,int age){
System.out.println("username = " + username + ", age = " + age);
}

方法的参数是int类型的,但是url中的请求参数是String类型,为什么这样没有发生报错呢?这是因为Spring MVC中含有自动类型转换器,能够帮我们自动进行类型转换,但是请求参数是Spring MVC不能够自动转换的类型的时候,例如Date=2020-10-11(它默认的是2020/10/11的形式),那么这时候需要我们来自己定义了,对应的步骤为:

  • 创建一个类Converter,使得这个类实现了接口Converter其中这个接口表示的是S类型转变成为了T类型,并且在Converter类中,实现它的方法converts
  • 在spring-mvc中,将上面创建的Converter添加到ConvertionServiceFactoryBean的converters属性中
  • 然后通过spring-mvc的mvc注解驱动,从而设置convertion-service属性的值。对应的代码如下:
 



    
        
            
            
        
    

对应的DateConverter代码为:

public class DateConverter implements Converter {
    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

controller3中的代码test8为:

@RequestMapping("/test8")
@ResponseBody
public void test8(Date date){
    System.out.println(date);
}
Spring MVC的文件上传

文件上传中,表单的要求为:

  • 表单项中含有file,即含有的标签
  • 表单的method属性为post
  • 表单的enctype属性要等于multipart/form-data

这时候,因为enctype的属性值为multipart/form-data,所以request调用getParameter来获取请求参数的值为null,因此不可以通过调用getParameter来获取表单项的值。因此我们需要利用FileUpload来获取表单项的元素。因此剩下操作应该是:

  • 导入commons-fileupload,commons-io的依赖到pom.xml文件中,对应的代码为:

    
        commons-io
        commons-io
        2.5
    
    
        commons-fileupload
        commons-fileupload
        1.3.1
    
    
  • 在spring-mvc.xml中配置文件上传解析器,对应的代码为:

    
           
           
            
       
    
  • 根据请求参数和方法参数名称一致的时候,请求参数的值就会赋值给方法参数,那么这时候我们就可以编写代码了。对应的代码:

    @RequestMapping("/test10")
    @ResponseBody
    public void test10(String username,MultipartFile[] uploadFiles) throws IOException {
        System.out.println(username);//普通表单项的值
        //文件表单项调用getName,获取的是表单项在jsp文件中的name,而不是文件名字
        //要获取上传的文件名字,需要调用getOriginalFileName才可以
        File dir = new File("E://IDEAworkspace/代码/Spring学习/upload/");
        if(!dir.exists()){
            dir.mkdir();
        }
        for(MultipartFile file : uploadFiles){
            String filename = file.getOriginalFilename();
            System.out.println(filename);
            //将调用transferTo,从而将当前的文件表单项复制到file中
            file.transferTo(new File( dir,filename));
        }
    }
    

    我们需要先访问upload.jsp页面,来选择要上传的文件,当点击提交按钮之后,聚会来到test10方法,所以upload.jsp的代码为:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    
        文件上传
    
    
        
    名字:
    文件1:
    文件2:
    文件3:

    当我们输入:localhost:8080/upload.jsp的时候,我们来到对应的界面为:

    点击提交之后,就会将对应的文件上传到了upload目录中:

Spring MVC中JdbcTemplate的操作

通过使用JdbcTemplate,可以简化一些操作,不象之前操作那样麻烦。所以,利用JdbcTemplate操作之前所需要做的准备:

  • 导入spring-jdbc和spring-tx的依赖到pom.xml中,并且因为需要连接数据库,同样需要导入java-connector-mysql依赖,并且还需要配置c3p0数据源,所以还需要再导入c3p0依赖

  • 由于我们需要利用spring整合junit进行测试,所以还需要再导入spring-test以及junit依赖,所以对应的代码为:

    
          org.springframework
          spring-jdbc
          5.0.1.RELEASE
        
        
          org.springframework
          spring-tx
          5.0.1.RELEASE
        
        
          org.springframework
          spring-test
          5.2.8.RELEASE
        
        
          junit
          junit
          4.12
          compile
        
    
        
          mysql
          mysql-connector-java
          8.0.16
        
        
          c3p0
          c3p0
          0.9.1.2
        
    
  • 当依赖导入完毕之后,我们要创建对应的表account,以及对应的类Account,这个表中的列主要是name以及balance.分别是String以及Integer类型。对应的代码为:

    public class Account {
        private String name;
        private Integer balance;
    
        public Account() {
        }
    
        public Account(String name, Integer balance) {
            this.name = name;
            this.balance = balance;
        }
    
        @Override
        public String toString() {
            return "Account{" +
                    "name='" + name + ''' +
                    ", balance=" + balance +
                    '}';
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getBalance() {
            return balance;
        }
    
        public void setBalance(Integer balance) {
            this.balance = balance;
        }
    }
    
    
  • 通过的形式,将JdbcTemplate,ComboPooleadDataSource添加到Spring MVC容器中,并且设置ComboPooleadDataSource中的driverClass,JdbcUrl,user,password的属性。同时我们需要为JdbcTemplate配置属性dataSource是ComboPooleadDataSource.所以对应的applicationContext.xml代码为:

    
    
        
        
        
            
            
            
            
        
        
            
        
    
    

    对应的jdbc.properties代码为:

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai
    jdbc.username=root
    jdbc.password=root
    

完成上述的操作之后,就可以进行测试了。其中JdbcTemplate主要有2个方法:

  • update:用来实现增删改操作的

  • query:用来实现查询的操作。如果希望返回的是单个对象,那么我们需要执行的是queryForObject(String sql,RowMapper)方法,其中我们需要将定义一个类XXXRowMapper,来实现RowMapper这个接口,这样,返回的是才是我们想要的对象。同样,如果执行的是query(String sql,RowMapper),这时候返回的是一个List,如果希望返回的是List,那么同样的,我们传递的RowMapper参数是我们自定义的。

    当然,我们也可以不用自定义RowMappper,我们直接传递BeanPropertyRowMapper(xxx.class)即可。所以如果我们需要获取List,调用的是query方法,这时候我们有2中方式可以获取:

    ①query(sql,new AccountRowMapper()),自定义RowMapper;

    ②传递参数BeanPropertyRowMapper(Account.class)即可,所以只需要调用**query(sql,new BeanPropertyRowMapper(Account.class))**方法即可

    同理,如果我们需要获取的是单个Account对象,那么我们也是有2中方式获取,一种是传递自定义的RowMapper对象,一种是传递BeanPropertyRowMapper(XXX.class)对象,只是这时候是调用queryForObject方法了:

    ①queryForObject(sql,new AccountRowMapper()),自定义RowMapper;

    ②传递参数BeanPropertyRowMapper(Account.class)即可,所以只需要调用**queryForObject(sql,new BeanPropertyRowMapper(Account.class))方法即可

如果我们希望要获取多少行之类的数据,这时候返回的是一个数字,此时调用queryForObject方法,并且返回的数据是一个基本的数据类型,并不需要我们进行封装,所以传递就是对应的类型的字节码对象即可。例如queryForObject(sql,Long.class)。

测试类JdbcTemplateTest代码为:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateTest {
    @Test
    public void test1() throws Exception {
        //配置ComboPooledDataSource
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai");
        dataSource.setUser("root");
        dataSource.setPassword("lf_MySQL");

        //创建JdbcTemplate对象,并且设置数据源
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        String sql = "insert into account(name,balance) values (?,?)";
        Object[] objs = new Object[]{"小王",5000};
        int row = jdbcTemplate.update(sql, objs);
        System.out.println(row);//返回值如果不为0,说明sql语句操作成功
    }

    
    @Autowired
    @Qualifier("jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test2(){
        //利用jdbcTemplate调用update方法进行修改操作
        String sql = "update account set balance = balance + 50000 where name = ?";
        int row = jdbcTemplate.update(sql, "小王");
        System.out.println(row);//如果不等于0,说明编辑成功
    }

    //利用JdbcTemplate来进行删除操作
    @Test
    public void test3(){
        String sql = "delete from account where name = ?";
        int row = jdbcTemplate.update(sql, "小王");
        System.out.println(row);//row不等于0的时候,说明删除操作成功
    }

    @Test
    public void test4(){
        //查询单个Account用户
        String sql = "select * from account where name = ?";
        Account account = (Account)jdbcTemplate.queryForObject(sql, new AccountRowMapper(), "AA");
        System.out.println(account);
    }
    @Test
    public void test5(){
        //查询多个Account用户
        String sql = "select * from account";
        List accounts = jdbcTemplate.query(sql, new AccountRowMapper());
        System.out.println(accounts);
    }
    
    @Test
    public void test6(){
        //查询多个用户的方式2
        String sql = "select * from account";
        List accounts = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Account.class));
        System.out.println(accounts);
    }

    @Test
    public void test7(){
        //查询单个用户的方式2
        String sql = "select * from account where name = ?";
        Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(Account.class), "AA");
        System.out.println(account);
    }

    //查询有多少行
    @Test
    public void test8(){
        String sql = "select count(*) from account";
        //因为返回的是一个数据,所以调用queryForObject即可
        //并且返回值是一个数据类型,所以不需要封装了
        Long count = jdbcTemplate.queryForObject(sql, Long.class);
        System.out.println(count);
    }
    
}

对应的AccountRowMapper代码为:

public class AccountRowMapper implements RowMapper {
    @Override
    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
        Account account = new Account();
        account.setName(resultSet.getString("name")); //name在数据库表中是String类型的,所以调用的是getString
        account.setBalance(resultSet.getInt("balance"));//balance在数据库表中的类型的是int类型的,所以调用的是getInt
        
        return account;
    }
}
Spring练习

这里主要通过练习一个管理系统(主要是管理用户的增删改查).

技术:Spring + MySQL + jsp

准备工作:

  1. 创建domain包下的User类以及Role类,对应的代码

    public class User {
        private Integer id;
        private String name;
        private List roles;
        private String email;
        private String phone;
        private String password;
    
        public User() {
        }
    
        public User(Integer id, String name, List roles, String email, String phone, String password) {
            this.id = id;
            this.name = name;
            this.roles = roles;
            this.email = email;
            this.phone = phone;
            this.password = password;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public List getRoles() {
            return roles;
        }
    
        public void setRoles(List roles) {
            this.roles = roles;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + ''' +
                    ", roles=" + roles +
                    ", email='" + email + ''' +
                    ", phone='" + phone + ''' +
                    ", password='" + password + ''' +
                    '}';
        }
    }
    
    

    Role代码:

    public class Role {
        private Integer id;
        private String name;
    
        public Role() {
        }
    
        public Role(Integer id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    
        @Override
        public String toString() {
            return "Role{" +
                    "id=" + id +
                    ", name='" + name + ''' +
                    '}';
        }
    }
    
    
  2. 创建对应的表user,role,user_role

  3. 创建对应的页面:login.jsp,dashboard.jsp,list.jsp等

要完成的工作:

  • 用户登录

    用户登录之前,我们需要对该用户的信息进行验证,如果输入的信息正确,那么就可以前往到对应的dashboard.jsp页面中,否则,将错误信息保存到request域中,然后转发到login.jsp页面。但是有几个地方需要注意的是:

    1. 如果这个用户没有办法在数据库中找到的时候,他并不是返回的是null,而是抛出的EmptyResultDataAccessException,所以我们不可以通过判断返回值User为null,从而证明无法找到这个用户,而是通过try-catch来解决,一旦捕捉到异常,就说明这个用户不存在,直接转发到login.jsp页面,并且给出错误提示。
    2. 需要注意的是,如果我们利用注解@Repository,@Service,@Controller,将对应的类添加到spring mvc容器的时候,需要注意组件的扫描。所以我们需要在applicationContext.xml,spring-mvc.xml中利用context命名空间,执行进行组件扫描,其中applicationContext.xml用来扫描service,dao等其他层的,而spring-mvc.xml则是扫描controller层的
    3. 实现方法映射的时候,要在对应的Controller类中添加@Controller注解,这样,才可以扫描各个组件,找到能够映射的方法,否则,如果下面的LoginController没有添加@Controller注解,那么这时候Spring MVC容器中没有这个Bean对象,那么就没有办法映射到对应的方法了。

    思路很简单,对应的代码为:

    @Controller //利用@Controller,从而将controller层中的类添加到Spring容器中
    @RequestMapping("/loginController") 
    public class LoginController {
        @Autowired
        private UserService userService;
    
        
        @RequestMapping("/login") 
        public String login(String username, String password, HttpServletRequest request){
            //判断是否为空
            if(username == null || username.length() <= 0){
                request.setAttribute("msg","用户名不可以为空");
                
                return "/login.jsp";
            }
            if(password == null || password.length() <= 0){
                request.setAttribute("msg","密码不可以为空");
                return "/login.jsp";
            }
            //利用userService,来查找这个姓名的用户
            try{
                User user = userService.query(username, password);
                //该用户存在,那么直接重定向到首页,并且将这个用户保存到session域中
                HttpSession session = request.getSession();
                session.setAttribute("user",user);
                return "redirect:/dashboard.jsp";
            }catch(EmptyResultDataAccessException e){
                request.setAttribute("msg","用户或者密码不存在");
                request.setAttribute("username",username);
                request.setAttribute("password",password);
                return "login.jsp";
            }
        }
    }
    
    

    对应的UserService代码:

    public interface UserService {
        public User query(String username, String password);
    }
    
    @Service("userService") //利用注解@Service,从而将这个类添加到Spring 容器中
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
        @Override
        public User query(String username, String password) throws EmptyResultDataAccessException {
            return userDao.query(username,password);
        }
    }
    
    

    对应的UserDao代码:

    public interface UserDao {
        User query(String username, String password);
    }
    
    @Repository("userDao") //利用注解@Repository,从而将Dao层中的类添加到Spring容器中
    public class UserDaoImpl implements UserDao {
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Override
        public User query(String username, String password) throws EmptyResultDataAccessException {
           String sql = "select * from user where name = ? and password = ?";
          User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(User.class), username, password);
          if(user != null){
              sql = "select role.id,role.name from role inner join user_role " +
                      " on role.id = user_role.role_id " +
                      " where user_role.user_id = ?";
              List roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Role.class), user.getId());
              user.setRoles(roleList);
          }
          return user;
        }
    }
    
    
  • 用户退出登录:主要是通过Session调用invalidate方法,从而注销当前的session,然后重定向到login.jsp页面,对应的代码为:

    @RequestMapping("/logout")
    public String logout(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.invalidate();
        //重定向到login.jsp页面
        return "redirect:/login.jsp";
    }
    
  • 用户查询以及删除

    获取所有的用户的时候,由于User的身份可能不只一个,所以这时候我们在User中定义一个List,而同样的,一个Role对应的用户也不只一个,所以这时候仅仅靠2张表user和role是不能够满足的,因此我们还需要定义第三张表role_user,从而实现多对多的关系。

    那么这时候我们要获取所有用户的时候,此时需要先知道user的id,然后根据user的id,来获取这个user对应的role_id,然后再查询role表,得到对应role_id的Role对象。然后再封装到对应的User中。

    各个表之间的关系为:

    而这时候需要注意的是,假设我们已经知道了User的id,那么这时候我们如果想知道这个User对应的role_id那么我们要查询表user_role,也即执行select role_id from user_role where user_id = xxxsql语句。然后再执行select * from role where id = ?获取Role。

    获取user的id之后,因为需要获取多个List,所以需要通过jdbcTemplate调用query(sql,new BeanPropertyRowMapper(Integer.class))来获取。然而,这时候就会发生报错:Failed to instantiate [java.lang.Integer],这是因为在Spring MVC中,只有需要获取自定义的对象的时候,才需要传递参数BeanPropertyRowMapper(xxx.class),而这时候Spring MVC中已经有了Integer这些类了,那么只能传递对应的字节码对象。但是传递字节码对象的query,只有queryForObject.

    所以这时候我们应该考虑联结的sql语句来解决。所以我们要获取List,假设我们已经知道了用户的id,则对应的sql语句为:

    String sql = "select role.id,role.name from "
                  " role inner join user_role " +
                  " on role.id = user_role.role_id " + 
                  " where user_role.user_id = ?";
    

    这样执行这个sql语句之后,就可以获取到对应的用户的List了。

    而在获取所有的user之后,我们需要返回到页面,并且展示用户列表,这时候我们需要通过el表达式来实现,通过标签c:forEach进行遍历即可。所以对应的list.jsp代码为:

    新增
    
        
                
    姓名 邮箱 角色 电话 操作
    ${user.name} ${user.email} ${role.name} ${user.phone} 编辑 删除

    效果展示如下所示:

  • 用户的添加

    对于用户的添加,首先我们点击新增之后,就会来到add.jsp页面,在这个页面中,我们需要输入要新添加的用户的信息,点击提交之后,才会将这个用户添加到数据库中,并且重新执行queryAll操作。

    而在添加操作中,因为需要知道所有用户的信息,所以我们在跳转到add.jsp页面之前,需要先获取所有的角色信息,然后再跳转到add.jsp页面。

    因为用户的角色可能不只一个,所以需要利用复选框。为了能够将提交的数据封装到一个User中,表单项的名字需要和User中的属性名字相同。由于在角色选中,采用的是复选框,那么我们这时候选中的角色需要用一个数组来封装,所以复选框中的name标签的值都相同,value属性则是每个角色对应的id。

    所以对应的add.jsp主要代码为:

        
    姓名:
    邮箱:
    电话:
    角色: ${role.name}

    对应的UserController中的添加操作的代码为:

    @RequestMapping("/preAdd")
    public String preAdd(HttpServletRequest request){
        //获取所有的角色
        List roles = roleService.queryAll();
        request.setAttribute("roles",roles);
        return "/add.jsp";//转发到add.jsp页面
    }
    @RequestMapping("/add")
    public String add(User user,int[] role_ids){
        //add.jsp中的每一个表单项的名字对应的是User中的成员名字,并且role_ids对应的是复选框的name属性的值
        userService.add(user,role_ids);
        return "queryAll";
    }
    

    对应UserDao代码为:

    @Override
    public void add(User user, int[] role_ids) {
        String sql = "insert into user (name,email,phone,password) values (?,?,?,?)";
        jdbcTemplate.update(sql, user.getName(), user.getEmail(), user.getPhone(), user.getPassword());
        //获取最新添加的用户的id
        sql = "select MAX(id) from user";
        Integer user_id = jdbcTemplate.queryForObject(sql, Integer.class);
        sql = "insert into user_role (user_id,role_id) values (?,?)";
        for(int role_id : role_ids){
            jdbcTemplate.update(sql,user_id,role_id);
        }
    }
    

    这里之所以不可以直接通过User来获取id,是因为上面我们添加用户的时候,并没有传递用户的id,所以这时候封装的User中的id是null。而因为将这个用户添加到数据库中,那么这个用户对应的就是最大的id,所以只要通过执行sql语句select MAX(id) from user,就可以获得新添加的用户的id了。

    测试结果如下所示:


    这时候,我们新添加的数据发生了乱码,这时候我们需要设置全局编码来解决,而再spring mvc中可以通过CharacterEncodingFilter来解决,对应的代码为:

    
        CharacterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
          encoding
          utf-8
        
      
      
        CharacterEncodingFilter
        
        /*
      
    

    这样就解决了乱码问题了。

  • 用户的编辑

    因为这个用户的角色是多对多的关系,所以一个用户可能会有多个角色。所以在进行编辑之前,首先需要获取所有的role,然后再来到update.jsp页面进行编辑。而编辑的时候,需要显示该用户的信息,所以在编辑之前,同样需要获取这个用户的信息。

    这时候,角色的显示,因为可能是由多个角色,所以需要利用就是默认选中,这时候只有由checked,那就是默认选中,不管checked的值是什么,如果没有checked,那么就是没有默认选中**。

    对应的代码为:

    姓名:
    邮箱:
    电话:
    角色: ${role.name} ${role.name}

    但是角色那里进行展示的时候,却不是我们想要的结果,如下图所示:

所有的角色都重复了3次,所以我们需要避免这种情况,但是怎么避免,暂时还没有想到。所以只能没有设置默认选中。也即复选框中代码为:


      ${role.name}

此时编辑界面不在支持默认选中的功能,然后我们提交之后,需要将编辑好的信息封装到User中,并且选中的role_id封装到一个数组中,然后在数据库中进行编辑操作。这时候我们先将当前用户原来的role都删除,然后再重新插入即可。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号