【SpringMVC】参数解析、中文乱码、拦截器、转换器、配置

在这里插入图片描述

URL映射

@RequestMapping用在类(必须是Controller)上:定义上一级路径

@RequestMapping("/user")
@RestController
public class HelloController {
    @RequestMapping("hello")
    public String hello(){
        return "Hello World!";
    }
}

示例URL:http://localhost:8080/user/hello
@RequestMapping用在方法上:URL与方法的映射

public class HelloController {
    @RequestMapping("hello")
    public String hello(){
        return "Hello World!";
    }
}

示例URL:http://localhost:8080/hello

参数解析

请求头参数

POST http://localhost:8080/test?id=99&name=国产

GET http://localhost:8080/test?id=99&name=国产

springMVC通过参数名匹配参数

请求体参数
json格式:

POST http://localhost:8080/getuser
Content-Type: application/json

{
  "id": 99,
  "name": "国产"
}

解析json格式需要导包:

<dependency>
	   <groupId>com.fasterxml.jackson.core</groupId>
	   <artifactId>jackson-core</artifactId>
	   <version>2.9.9</version>
</dependency>
<dependency>
	   <groupId>com.fasterxml.jackson.core</groupId>
	   <artifactId>jackson-databind</artifactId>
	   <version>2.9.9.3</version>
</dependency>

然后方法参数加上@RequestBody注解

	@RequestMapping("home")
    public User home(@RequestBody User user){
        return user;
    }

将返回值对象转成json格式,例如:
user.toString( );是字符串User(id=99,name=国产)
这不是json格式,导入的依赖自动把对象转成json格式

{
  "id": 99,
  "name": "国产"
}

一般格式:

POST http://localhost:8080/getuser
Content-Type: application/x-www-form-urlencoded

id=99&name=国产

转换器

将字符串转换成复杂类型,例如将时间转换成Date类型,我们需要写转换器
请求头:

POST http://localhost:8080/date?date=2020-01-01 10:10:10
Content-Type: application/x-www-form-urlencoded

转换器:

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StringDateConverter implements Converter<String,Date> {
    private SimpleDateFormat simpleDateFormat=
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");



    @Override
    public Date convert(String time) {
        Date date=null;
        try {
            date=simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

使转换器生效:dispatcher-servlet.xml

<mvc:annotation-driven conversion-service="conversionService2">
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="defaultCharset" value="utf-8" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
<bean id="conversionService2" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.bailiban.convecter.StringDateConverter"></bean>
        </set>
    </property>
</bean>

如果是这种json格式请求体的post请求:

POST http://localhost:8080/date
Content-Type: application/json

{
  "id": 99,
  "name": "国产"
  "date": "2020-01-01 10:10:10"
}

那么json依赖包会自动处理,我们自己写的转换器不会用到;
利用json的处理,我们需要在类里面添加注解,如下:

public class User {
    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date date;
}

中文乱码问题

原因:web容器、spring容器默认字符编码是ISO_8859_1,不支持中文。

DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;

解决方法:
1.在请求头指定编码

POST http://localhost:8080/test?id=99&name=国产
Accept: text/html;charset=utf8
Content-Type: application/json;charset=utf8

上述设置编码后,服务器端不会产生乱码
2.配置xml
解决返回值乱码:WEB-INF/dispatcher-servlet.xml

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="defaultCharset" value="utf-8" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

或者(不常用)

@RequestMapping(value = "home",produces = {"text/html,charset=utf-8"})
public String home(User user){
	   return "home";
}

解决请求乱码:WEB-INF/web.xml
tomcat已经帮我们解决了此问题,默认缺省编码是utf8,所以这个可以不配

<!--    <filter>-->
<!--        <filter-name>encodingFilter</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>-->
<!--        <init-param>-->
<!--            <param-name>forceRequestEncoding</param-name>-->
<!--            <param-value>true</param-value>-->
<!--        </init-param>-->
<!--    </filter>-->
<!--    <filter-mapping>-->
<!--        <filter-name>encodingFilter</filter-name>-->
<!--        <servlet-name>dispatcher</servlet-name>-->
<!--    </filter-mapping>-->

3.写一个拦截器(解决请求乱码
@Override
public boolean preHandle
该方法在handle之前执行,所以在这里设置编码为utf-8就不会乱码
@Override
public boolean postHandle
而此方法是在handle之后执行

public class CharEncodingInterceptor extends HandlerInterceptorAdapter {
    public CharEncodingInterceptor() {
        super();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setCharacterEncoding("utf-8");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        System.out.println("postHandle");
//        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }
}

写完拦截器,需要使他生效,得配置一下:dispatcher-servlet.xml

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean id="charEncodingInterceptor" class="com.bailiban.intercepter.CharEncodingInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

idea的Tomcat运行乱码解决办法:
VM options:-Dfile.encoding=utf-8
在这里插入图片描述
找到下图位置添加-Dfile.encoding=utf-8
在这里插入图片描述
在这里插入图片描述

方法执行:java反射调用方法

method.invoke(object,args...)

返回值处理

@Controller:返回html、jsp页面
@RestController:返回json

返回页面时controller这么写:

@Controller
public class UserController {

    private static Map<Integer,User> userMap=new HashMap<>();
    static {
        userMap.put(1,new User(1,"one一"));
        userMap.put(2,new User(2,"two二"));
        userMap.put(3,new User(3,"three三"));
    }

    @RequestMapping("login")
    public String login(User user){
        System.out.println(user.toString());
        if(user.getId()!=null){
            User user1=userMap.get(user.getId());
            if(user.getName().equals(user1.getName())){
                System.out.println(user1.toString());
                return "redirect:home";
            }
        }
        return "login";
    }

    @RequestMapping("home")
    public String home(User user){
        return "home";
    }
}

需要配置资源扫描:dispatcher-servlet.xml
我的jsp文件路径:WEB-INF/pages/jsps/login.jsp,则配置为:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix" value="WEB-INF/pages/jsps/" />
        <property name="suffix" value=".jsp" />
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值