SpringMVC笔记

SpringMVC简介

  SpringMVC是基于java的控制层(controller控制器)Web框架,属于Spring FrameWork的后续产品。

  1. 总体SSM结构图
    web架构图
  2. SpringMVC执行流程图
    SpringMVC组件执行流程

常用注解

处理器注解(controller)

@RequestMapping的属性

	value:用于指定请求的 URL。它和 path 属性的作用是一样的。
	method:用于指定请求的方式。
	params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的 key 和 value 必须和
配置的一模一样。
	  例如:
		params = {"accountName"},表示请求参数必须有 accountName
		params = {"moeny!100"},表示请求参数中 money 不能是 100。
	headers:用于指定限制请求消息头的条件。
注意:
	以上四个属性只要出现 2 个或以上时,他们的关系是与的关系。
@Controller
//标识一级目录可以不写
@RequestMapping("/helloM")
public class HelloMVC  {
    //path或value表示二级目录或一级目录(类注解没写时)
    //表示限制的属性:
    //      method = {RequestMethod.GET} 只能get请求才能访问此方法
    //      headers = {"Accept"} 请求必须携带Accept这个请求头
    //      params = {"username"} 请求必须携带username Key信息
    //      params = {"username=tdte"} 请求必须携带"username" Key信息和"tdte" Value信息
    @RequestMapping(path = "/hello",method = {RequestMethod.GET},headers = {""},params = {"username"})
    public String pringHello() {
        System.out.println("hello mvc");
        return "success";
    }
}

请求参数绑定

简单类型
//springmvc可以根据请求的参数的key值匹配参数
//如前端传过来参数username=tdte
//则下面打印   用户名:tdte
@RequestMapping(params = "/param")
public String testParam(String username, String password) {
    System.out.println("testParam.....");
    System.out.println("用户名:" + username);
    System.out.println("密码:" + password);
    return "success";
}
实体类型的自动参数绑定
//spring 会根据前端参数的key值自动绑定pojo类的set属性
@RequestMapping(path = "/user")
public String testPojo(User user) {
    System.out.println("testParam.....");
    System.out.println(user);
    return "success";
}

测试用实体类:

import lombok.Data;

@Data
public class Account {
    private String aname;
    private String apwd;
}

@Data
public class User implements Serializable {
    private String uname;
    private String upwd;
    private Double umoney;
    //引用Account类
    private Account account;
}

前端测试表单:

<!--注意 post表单如果提交到后台会出现中文乱码问题-->
<form action="helloM/user" method="post">
    用户名称:<input type="text" name="uname"><br/>
    密码:<input type="text" name="upwd"><br/>
    金额:<input type="text" name="umoney"><br/>
    <!--  注意此处 引用类型用.进行深层赋值  -->
    账户名称:<input type="text" name="account.aname"><br/>
    账户密码:<input type="text" name="account.apwd"><br/>
    <input type="submit" value="提交"><br/>
</form>

复杂类型自动参数绑定(集合)
  • 使用到了类:
    测试pojo:
@Data
public class User implements Serializable {
    private String uname;
    private String upwd;
    private Double umoney;

    private List<Account> list;
    private Map<String,Account> map;
}

@Data
public class Account {
    private String aname;
    private String apwd;
}

测试处理器:

    //spring 会根据前端参数的key值自动绑定pojo类的set属性
    @RequestMapping(path = "/user")
    public String testPojo(User user) {
        System.out.println("testParam.....");
        System.out.println(user);
        return "success";
    }

前端表单表达式:

<form action="helloM/user" method="post">
    用户名称:<input type="text" name="uname"><br/>
    密码:<input type="text" name="upwd"><br/>
    金额:<input type="text" name="umoney"><br/>

	<!--注意此处表达式和上面的pojo属性的匹配-->
    账户名称:<input type="text" name="List[0].aname"><br/>
    账户密码:<input type="text" name="list[0].apwd"><br/>
	<!--注意:map的key需要手动写入或者前端js-->
    账户名称:<input type="text" name="map['tdte'].aname"><br/>
    账户密码:<input type="text" name="map['tdte'].apwd"><br/>
    <input type="submit" value="提交"><br/>
</form>

自定义类型转换

  我们提交数据的时候,request中的数据都是以String的类型存在的,Spring会做一些类型转换,将这些数据转换成我们所需要的数据类型(int、float等)。对于日期来说,Spring支持的格式是2020/01/10,当我们传入2020-01-10,程序会报错,这时候就需要我们自定义类型转换器来满足我们的需要。

测试用pojo类:

@Data
public class Account {
    private String aname;
    private String apwd;
    private Date date;
}

定义转换类,实现Converter接口,在重写方法中对业务进行实现:

public class StringToDateConverter implements Converter<String, Date> {
    /**
     * 自定义类型转换器,手动把字符串转换成Date类型
     *
     * @param source 被转换的字符串
     * @return 转换后的字符串
     */
    @Override
    public Date convert(String source) {
        if ("".equals(source) || source == null) {
            throw new RuntimeException("参数为空");
        }

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //字符串转换
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("字符串解析异常");
        }
    }
}

配置spring的xml文件:

<!--  注册自定义类型转换器  -->
<bean id="stringToDateConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="top.tdte.util.StringToDateConverter"/>
        </set>
    </property>
</bean>
<!--在注解驱动中添加属性 conversion-service-->
<mvc:annotation-driven conversion-service="stringToDateConversionService"/>

测试方法:

 //spring 会根据前端参数的key值自动绑定pojo类的set属性
 @RequestMapping(path = "/account")
 public String testConverter(Account account) {
     System.out.println("testConverter.....");
     System.out.println(account);
     return "success";
 }

配置springmvc过滤器解决中文乱码问题

在web.xml中配置:

<!--  添加字符集过滤器-->
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <!--   过滤范围 根目录及其子目录     -->
    <url-pattern>/*</url-pattern>
</filter-mapping>

常用参数注解
RequestParam注解:
@Controller
@RequestMapping("/comm")
public class commonAnnotation {
    @RequestMapping("/test")
    // @RequestParam 表示前端传入的参数可以不必须匹配方法的参数名称
    // 可以用name或value属性进行映射,
    // required 属性默认为true表示前端name表单属性必须与name匹配,否则404
    public String test(@RequestParam(name = "name") String username) {
        System.out.println("方法执行");
        return "success";
    }
}
@RequestBody:
//获得请求体 就是?后面的全部键值
    //注意参数不能与前端表单name属性重名,否则优先使用同名匹配
    @RequestMapping("/test1")
    public String test1(@RequestBody String body) {
        System.out.println("方法执行");
        System.out.println(body);
        return "success";
    }
@PathVaribale:
//根据rest风格匹配具体请求的方法
//rest风格是根据同一个url不同请求方式进行区分的,或根据{}占位符的值进行区分
//下面是根据占位符进行区分,并且获取占位符参数
//前端传入的url可以为comm/test1/10定位要执行的方法
@RequestMapping("/test1/{sid}")
public String test2(@PathVariable("sid") String id) {
    System.out.println("方法执行....");
    System.out.println(id);
    return "success";
}

RequestHeader注解:
//获取头信息 Accept头的值
@RequestMapping(path="/hello")
public String sayHello(@RequestHeader(value="Accept") String header) {
	System.out.println(header);
	return "success";
}
CookieValue
@RequestMapping(path="/hello")
public String sayHello(@CookieValue(value="JSESSIONID") String cookieValue) {
	System.out.println(cookieValue);
	return "success";
}
ModelAttribute:
  1. 有返回值:

注意:前端必须没有这个省略的pojo实体类属性的表单,否则会出现在自动参数绑定上会出现异常。

@RequestMapping("/test3")
public String test3(Account account) {
    System.out.println("方法执行....");
    System.out.println(account);
    return "success";
}

//如果请求本类的方法,这个方法会先执行,这个注解一般用于附初始值。
//有返回值值被ModelAttribute修饰的方法
@ModelAttribute
public Account testModelAttribute(String aname) {
    System.out.println("ModelAtteribute.....");
    Account ac = new Account();
    ac.setAname(aname);
    ac.setApwd("1234");
    ac.setDate(new Date());
    return ac;
}
  1. 无返回值:
// 参数注解用于取出map中的匹配的value值
@RequestMapping("/test3")
public String test3(@ModelAttribute("acc") Account account) {
    System.out.println("方法执行....");
    System.out.println(account);
    return "success";
}

// 添加一个参数map其K代表一个id号,用于其被引用方法的关联,如上面方法用于修饰Account的参数的注解,
// V用来存储初始化的pojo对象
@ModelAttribute
public void testModelAttribute(String aname, Map<String,Account> map) {
    System.out.println("ModelAtteribute.....");
    Account ac = new Account();
    ac.setAname(aname);
    ac.setApwd("1234");
    ac.setDate(new Date());
    map.put("acc",ac);
}
SessionAttributes:

@Controller
@RequestMapping("/comm")
//把model中的域对象key=smg的值从request域对象拷贝到session中
@SessionAttributes("msg")
public class commonAnnotation {
    @RequestMapping("/test4")
    public String test4(Model model) {
        System.out.println("方法执行....");
        //model底层会存入request域对象中,前端jsp表达式就可以取出
        model.addAttribute("msg", "消息测试");
        return "success";
    }

    @RequestMapping("/test5")
    public String test5(ModelMap modelMap, SessionStatus sessionStatus) {
        System.out.println("方法执行....");

        //取出session域对象的值
        String msg = (String) modelMap.getAttribute("msg");
        System.out.println(msg);

        //删除session域对象
        sessionStatus.setComplete();
        return "success";
    }
}

响应数据和结果视图

方法返回值跳转

视图解析器:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

根据返回值配合视图解析器跳转:

 @RequestMapping("/hello")
 public String hello() {
     System.out.println("hello......");
     return "success";
 }

void返回值跳转

  无返回值时springMVC会根据视图解析器跳转到/WEB-INF/jsp/Mtest/hello1.jsp页面(根据RequestMapping值查找文件位置,找不到为404)此方法繁琐,一般不用此方法跳转。
Alt

@Controller
@RequestMapping("/Mtest")
public class TestController {
	//跳转测试
	@RequestMapping("/hello1")
	public void hello1() {
	    System.out.println("hello1......");
	}
}

使用传统ServletAPI跳转:

/**
 * 是void 不使用视图解析器
 * 请求转发一次请求,不用编写项目的名称
 */
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
    System.out.println("testVoid方法执行了...");
    // 编写请求转发的程序
    // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);

    // 重定向
    // response.sendRedirect(request.getContextPath()+"/index.jsp");

    // 设置中文乱码
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");

    // 直接会进行响应
    response.getWriter().print("你好");

    return;
}

重定向和转发的区别:

转发是一次请求,不需要携带项目名称如:
	request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
重定向是重新发了一次请求,需要携带项目名称: 
	response.sendRedirect(request.getContextPath()+"/index.jsp");

使用ModelAndView对象

  实际上,返回字符串进行跳转,底层会使用到ModelAndView对象。

@RequestMapping("/test3")
public ModelAndView test3(User user) {
    System.out.println("test3......");
    //创建对象
    ModelAndView modelAndView = new ModelAndView();
    //把user对象存储到modelAndView对象中,也会把user对象存入到request对象,key=msg
    modelAndView.addObject("msg",user);
    //跳转到哪个页面
    modelAndView.setViewName("success");
    return modelAndView;
}

框架中的转发与重定向关键字:forward redirect

@RequestMapping("/test4")
public String  test4(User user) {
    System.out.println("test4......");
    //使用forward关键字进行 请求转发
    return "forward:/WEB-INF/jsp/success.jsp";

    //注意:网站不能直接请求或重定向获取web-inf下的资源,但请求转发能获取,是因为转发没有建立新的请求。
    //      在springmvc中使用redirect关键字进行中定向可以省略项目名称,底层会加上ContextPath。
    return "redirect:springmvc02/WEB-INF/jsp/success.jsp";
}

静态资源被DispatcherServlet(前端控制器)拦截问题

问题描述
在web文件夹下有一个js/jquery.min.js文件。并且前端引用这个资源。由于前端是文件路径引用的,因此会被DispatcherServlet拦截调。

<script src="js/jquery.min.js"></script>

<script>
    $(function () {
        $("#btn").click(function () {
            alert("弹窗测试");
        });
    });
</script>

解决方法
在springmvc-config.xml中添加过滤标签

<!--  告诉前端控制器不拦截静态资源 其他文件夹类似 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->

或者使用默认的过滤器:

<mvc:default-servlet-handler/>

异步交互与ResponseBody响应json数据

异步交互需要使用到jQuery
前端Ajax技术格式:

$.post({
    url: "${pageContext.request.contextPath}/Mtest/test6",
    data: {"name": $("#txt").val()},
    success: function (data, status) {
        $("#sname").html(data.toString());
        console.log(status);
        console.log(data.toString());
    }
})

json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

控制层响应设置:

// produces 防止响应json中有中文乱码问题
@RequestMapping(path = "/test7",produces = "text/html;charset=UTF-8")
//ResponseBody 注解 把user属性转换成json格式,返回给前端页面。
public @ResponseBody User test7(@RequestBody User user) {
    System.out.println("test7......");
    System.out.println(user);

    user.setName("haha");
    user.setAge(10);
    return user;
}

文件上传

前端测试代码:

<form action="userUp/upload" method="post" enctype="multipart/form-data">
    <%-- 注意文件上传必须有那么熟悉,否则后端得不到数据 --%>
    <%--  注释:只有设置了 name 属性的表单元素才能在提交表单时传递它们的值  --%>
    文件上传:<input type="file" name="pic">
    <input type="submit" value="上传">
</form>
传统方式文件上传:

文件上传依赖包:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
@RequestMapping(path = "/upload")
    public String upload(HttpServletRequest request) {
        System.out.println("upload.....");
        String uploadPath = request.getSession().getServletContext().getRealPath("/upload/");
        File path = new File(uploadPath);
        if (!path.exists()) {
            path.mkdirs();
        }
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        try {
            List<FileItem> items = fileUpload.parseRequest(request);
            for (FileItem item : items) {
                //检测是否是普通表单,true略过
                if (item.isFormField()) {
                    continue;
                }
                String name = item.getName();
                String uuid = UUID.randomUUID().toString().replace("-", "");
                //写入本地磁盘
                item.write(new File(path, uuid + name));
                //清空缓存
                item.delete();
            }
        } catch (Exception e) {
            throw new RuntimeException("上传文件解析异常");
        }
        return "success";
    }

SpringMVC传统方式文件上传

文件上传流程图:
在这里插入图片描述

<!-- 文件解析器对象,要求id名称必须是multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 配置最大上传文件大小 单位是字节 B-->
    <property name="maxUploadSize" value="104857600"/>
    <property name="defaultEncoding" value="utf-8"/>
</bean>

SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的name属性名称相同。

@RequestMapping(path = "/upload1")
public String upload1(HttpServletRequest request, MultipartFile upload) throws IOException {
    System.out.println("upload1.....");
    String uploadPath = request.getSession().getServletContext().getRealPath("/upload/");
    File path = new File(uploadPath);
    if (!path.exists()) {
        path.mkdirs();
    }
    //获取源文件名称
    String filename = upload.getOriginalFilename();
    //保存到磁盘
    upload.transferTo(new File(path,filename));

    return "success";
}
SpringMVC跨服务器方式文件上传

业务服务器配置:
在业务服务器端导入依赖的:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-core</artifactId>
    <version>1.18.1</version>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.18.1</version>
</dependency>

参考博客:https://www.cnblogs.com/libo0125ok/p/7773898.html
跨服务器文件上传,此方法配置在业务服务器,非文件服务器

@RequestMapping(path = "/upload2")
public String upload2(MultipartFile upload) throws IOException {

    System.out.println("跨服务文件测试开始");
    if (upload == null) {
        System.out.println("文件上传为空");
        return "success";
    }
    //存储文件服务器地址 此文件位置一另一个tomcat 的webapp/ROOT/uploads下
    String url = "http://localhost:15500/uploads/";

    //获取源文件名称
    String filename = upload.getOriginalFilename();

    Client client = Client.create();
    // 注意斜杠/问题
    //和文件服务器进行连接
    WebResource webResource = client.resource(url + filename);
    //进行上传到文件服务器 注意转换成字节码传输
    webResource.put(upload.getBytes());
    System.out.println("文件上传成功");
    return "success";
}

文件服务器配置:
在文件服务器tomcat中conf/web.xml配置如下

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    ····
    <!--关闭只读选项-->
    <init-param>
        <param-name>readonly</param-name>
        <param-value>false</param-value>
    </init-param>
    ····
</servlet>

异常处理(配置错误页面)

SpringMVC异常处理流程图:
Alt

  1. 模拟发生异常:
@RequestMapping("/exp")
//声明抛出异常
public String test2() throws Exception {
    System.out.println("异常方法");

    try {
        //模拟服务层发生异常
        int i = 1 / 0;
    } catch (Exception e) {
        throw new MyException("用户查询异常");
    }

    return "success";
}
  1. 自定义异常类:
public class MyException extends Exception {
    private String message;

    public MyException(String messeg) {
        this.message = messeg;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
  1. 配置异常处理器:
//实现异常处理接口
@Component("myExceptionResolver")
public class MyExceptionResolver implements HandlerExceptionResolver {
    //这里只是用了一个参数ex
    @Override
    public ModelAndView resolveException(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object handler, Exception ex) {

        MyException me = null;
        if (ex instanceof MyException) {
            me = (MyException) ex;
        }else {
            me = new MyException("系统正在维护");
        }
        
        ModelAndView modelAndView = new ModelAndView();
        //这里选择携带异常信息给前端
        modelAndView.addObject("errorpage", me.getMessage());
        //跳转到错误页面
        modelAndView.setViewName("error");

        return modelAndView;
    }
}

拦截器

  • 步骤:
    • 编写自定义拦截器必须实现HandlerIntercept接口
    • 在spring中配置拦截器
注意拦截器的执行流程:(注意点)

在这里插入图片描述

自定义拦截类:

public class MyIntercept implements HandlerInterceptor {
    /**
     * 预处理,controller方法执行前执行
     *
     * @return true表示放行,
     * 如果有下一个拦截器执行下一个拦截器没有就,执行controller里面的方法
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("预处理拦截器执行了");
        return true;
    }

    /**
     * 后处理方法,controller方法执行后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("后处理拦截器执行了");
    }

    /**
     * 最后执行方法,jsp等前端页面渲染完成了后执行,
     * 一般用于释放资源等操作。
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("最终处理拦截器执行了");
    }
}

在spring xml文件中配置拦截器:

<!--  在spring xml文件中配置拦截器-->
<mvc:interceptors>
    <!-- interceptors标签下可以配置多个自定义拦截器 -->
    <mvc:interceptor>
        <!-- 配置要拦截的方法 -->
        <mvc:mapping path="/user/*"/>
        <!-- 配置不要拦截的方法 -->
        <mvc:exclude-mapping path="/"/>
        <!-- 把自定义拦截器加入到spring中来 -->
        <bean class="top.tdte.intercept.MyIntercept"/>
    </mvc:interceptor>

    <!--注意顺序问题:如配置多个拦截器,则会顺序执行-->
    <mvc:interceptor>
        ···
    </mvc:interceptor>
</mvc:interceptors>

其他问题

路径符号问题:

访问资源的时候,前面加上"/",表示绝对路径,从根路径开始去寻找资源。
访问资源的时候,前面不加"/",表示相对路径,从上一级上下文路径中去寻找资源。

SpringMVC的拦截器中:
“/” 拦截所有请求,包括静态资源的请求,但不会拦截.jsp。
“/*”会匹配一级路径,如/a,/b。
"/**"会匹配所有路径,如/a/b,/a/b/c等。


在controller类方法里获得Servlet原生对象:

只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象


springmvc 发送ajax中文乱码的几种解决办法:

使用spingmvc,在JS里面通过ajax发送请求,并返回json格式的数据,从数据库拿出来是正确的中文格式,展示在页面上就是错误的,因此有如下几种解决办法。

方法一: 在@RequestMapping里面加入produces = “text/html;charset=UTF-8”

@RequestMapping(value = "/configrole", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")  
public @ResponseBody String configrole() {  
  ......  
} 

方法二:

因为在StringHttpMessageConverter里面默认设置了字符集是ISO-8859-1

所以拿到源代码,修改成UTF-8并打包到spring-web-3.2.2.jar

public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String>  
{  
  public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");  
  ..........  
}  

方法三:

修改org.springframework.http.MediaType它的构造方法的参数,并在applicationContext-mvc.xml 加入配置

public MediaType(String type, String subtype, Charset charset) {  
    super(type, subtype, charset);  
}  
<bean id="stringHttpMessageConverter"  
    class="org.springframework.http.converter.StringHttpMessageConverter">  
    <property name="supportedMediaTypes">  
        <list>  
            <bean class="org.springframework.http.MediaType">  
                <constructor-arg value="text" />  
                <constructor-arg value="plain" />  
                <constructor-arg value="UTF-8" />  
            </bean>  
        </list>  
    </property>  
</bean>  

方法四:

直接将org.springframework.http.converter.StringHttpMessageConverter 里面的属性defaultCharset设置成utf-8

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">  
     <property name="defaultCharset" value="UTF-8"/>  
</bean>  

idea中web工程不能自动打jar包问题
  • 如果选择的是普通的maven工程,后添加的web支持框架,就需要手动建立lib目录,并添加依赖包。
    如果选择的是maven继承的web模板,则idea会自动把依赖jar包发布到服务器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值