GVKun编程网logo

Spring中的@RequestParam如何处理Guava的Optional?

13

如果您对Spring中的@RequestParam如何处理Guava的Optional?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于Spring中的@RequestPar

如果您对Spring中的@RequestParam如何处理Guava的Optional?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于Spring中的@RequestParam如何处理Guava的Optional?的详细内容,并且为您提供关于@RequestParam 和 @RequestBody 的在 spring boot 中的用法、@RequestParam 注解使用:Name for argument type [java.lang.String] not available, and parameter name inf...、Java Spring @RequestParam JSP、java stream如何实现guava的partition的有价值信息。

本文目录一览:

Spring中的@RequestParam如何处理Guava的Optional?

Spring中的@RequestParam如何处理Guava的Optional?

@RequestMapping(value = "/contact.html", method = RequestMethod.POST)public final ModelAndView contact(        @RequestParam(value = "name", required = false) Optional<String> name) {

如果不需要参数值并且什么也不发送,Spring如何@RequestMapping处理Guava库中的Optionalfrom

那将会:

  • 设置 null
  • 设置 Optional.absent()

可以Optional.fromNullable(T)用来接受请求吗?

答案1

小编典典

编辑(2015年10月): Spring 4 java.util.Optional开箱 即用Optional(从Java 8开始)处理并
保证其 本身不为null ,但最初的问题是关于Guava
在此特定情况下强烈反对com.google.common.base.Optional使用哪种用法@RequestParam(因为它 可以
为null)。

原始答案 (关于番石榴Optional):

不要那样做,只需使用String并让Spring null以它的方式处理即可。

Optional<T>应该用作
返回值
,很少用作参数。在这种特殊情况下,Spring会将缺少的"name"参数映射到null,因此,即使在实现自定义属性编辑器后,您也将完成null检查:

@RequestMapping("foo")@ResponseBodypublic String foo(@RequestParam(required = false) final Optional name) {  return "name: " + (name == null ? "null" : name.get());}

这是完全不必要的(和滥用Optional),因为可以通过以下方法实现:

@RequestMapping("foo")@ResponseBodypublic String foo(@RequestParam(required = false) final String name) {  return "name: " + (name == null ? "null" : name);}

@RequestParam 和 @RequestBody 的在 spring boot 中的用法

@RequestParam 和 @RequestBody 的在 spring boot 中的用法

一、现象

    由于项目是前后端分离,因此后台使用的是 spring boot,做成微服务,只暴露接口。接口设计风格为 restful 的风格,在 get 请求下,后台接收参数的注解为 RequestBody 时会报错;在 post 请求下,后台接收参数的注解为 RequestParam 时也会报错。

二、原因

@RequestParam

用来处理 Content-Type: 为 application/x-www-form-urlencoded 编码的内容。(Http 协议中,如果不指定 Content-Type,则默认传递的参数就是 application/x-www-form-urlencoded 类型)

RequestParam 可以接受简单类型的属性,也可以接受对象类型。 例如

public R getCompletedInfo(@RequestParam Map<String, Object> params)
public R getCompletedInfo(@RequestParam AuditDecisionEntity auditDecisionEntity)
public R getCompletedInfo(@RequestParam String id)

都可以获取到数据。

实质是将 Request.getParameter () 中的 Key-Value 参数 Map 利用 Spring 的转化机制 ConversionService 配置,转化成参数接收对象或字段。

注意:

Content-Type: application/x-www-form-urlencoded 的请求中, 

get 方式中 queryString 的值,和 post 方式中 body data 的值都会被 Servlet 接受到并转化到 Request.getParameter () 参数集中,所以 @RequestParam 可以获取的到

@RequestBody

处理 HttpEntity 传递过来的数据,一般用来处理非 Content-Type: application/x-www-form-urlencoded 编码格式的数据。

  • GET 请求中,因为没有 HttpEntity,所以 @RequestBody 并不适用。
  • POST 请求中,通过 HttpEntity 传递的参数,必须要在请求头中声明数据的类型 Content-Type,SpringMVC 通过使用 HandlerAdapter 配置的 HttpMessageConverters 来解析 HttpEntity 中的数据,然后绑定到相应的 bean 上。

三、总结

  • 在 GET 请求中,不能使用 @RequestBody。
  • 在 POST 请求,可以使用 @RequestBody 和 @RequestParam,但是如果使用 @RequestBody,对于参数转化的配置必须统一。另贴上例子:

 get 请求

  前台:

$.getJSON(serverPath + "project/engineering/completedcheck/",{"gongchengid":GetUrlParam("id")}, function (result) {

后台:

@RequestMapping("/completedcheck")
public R completedcheck(@RequestParam Map<String, Object> params){

post 请求

前台:

$.post(serverPath + ''project/engineering/updateData'', JSON.stringify({"id":GetUrlParam("id"),"gongchengztxsz":"基本信息"}), function (result) {

后台:

@RequestMapping("/updateData")
public R updateData(@RequestBody EngineeringEntity engineering){

     

@RequestParam 注解使用:Name for argument type [java.lang.String] not available, and parameter name inf...

@RequestParam 注解使用:Name for argument type [java.lang.String] not available, and parameter name inf...

详细错误信息

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.] with root cause java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
2018-03-01 03:39:35.038 ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet][http-nio-8080-exec-1]: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.] with root cause java.lang.IllegalArgumentException: Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:168)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.getNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:145)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:94)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

 

解决思路

需要指定 @RequestParam 的 name 属性值

源码分析

 AbstractNamedValueMethodArgumentResolver.java

private NamedValueInfo getNamedValueInfo(MethodParameter parameter) {
    NamedValueInfo namedValueInfo = this.namedValueInfoCache.get(parameter);
    if (namedValueInfo == null) {
        namedValueInfo = createNamedValueInfo(parameter);
        namedValueInfo = updateNamedValueInfo(parameter, namedValueInfo);
        this.namedValueInfoCache.put(parameter, namedValueInfo);
    }
    return namedValueInfo;
}

/**
 * Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically
 * retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}.
 * @param parameter the method parameter
 * @return the named value information
 */
protected abstract NamedValueInfo createNamedValueInfo(MethodParameter parameter);

/**
 * Create a new NamedValueInfo based on the given NamedValueInfo with sanitized values.
 */
private NamedValueInfo updateNamedValueInfo(MethodParameter parameter, NamedValueInfo info) {
    String name = info.name;
    if (info.name.isEmpty()) {
        name = parameter.getParameterName();
        if (name == null) {
            throw new IllegalArgumentException(
                    "Name for argument type [" + parameter.getNestedParameterType().getName() +
                    "] not available, and parameter name information not found in class file either.");
        }
    }
    String defaultValue = (ValueConstants.DEFAULT_NONE.equals(info.defaultValue) ? null : info.defaultValue);
    return new NamedValueInfo(name, info.required, defaultValue);
}

RequestParamMethodArgumentResolver.java
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
    RequestParam ann = parameter.getParameterAnnotation(RequestParam.class);
    return (ann != null ? new RequestParamNamedValueInfo(ann) : new RequestParamNamedValueInfo());
}


private static class RequestParamNamedValueInfo extends NamedValueInfo {

    public RequestParamNamedValueInfo() {
        super("", false, ValueConstants.DEFAULT_NONE);
    }

    public RequestParamNamedValueInfo(RequestParam annotation) {
        super(annotation.name(), annotation.required(), annotation.defaultValue());
    }
}

 

Java Spring @RequestParam JSP

Java Spring @RequestParam JSP

当前控制器代码:

    @RequestMapping(value = "/city", method = RequestMethod.POST)public String getWeather(@RequestParam("city") int city_id,                             @RequestParam("text") String days, //this gives errrors, when i remove this line, then it is okay                             Model model) {    logger.debug("Received request to show cities page");    //int city =    // Attach list of subscriptions to the Model    model.addAttribute("city",  service.getCity(city_id));    // This will resolve to /WEB-INF/jsp/subscribers.jsp    return "city";}

这是我的JSP文件(视图):

    <form method="post" action="/spring/krams/show/city">Vali linn<select name="city">    <c:forEach items="${cities}" var="city">        <option value="<c:out value="${city.id}" />"><c:out value="${city.city}" /></option>    </c:forEach></select><br>Vali prognoos N päeva kohta(kirjuta 1 hetkese ilma jaoks)<input type="text name="text"><input type="submit" value="Test" name="submit" /></form>

我想从名为TEXT的文本框中获取一个值,但是当我按下Submit按钮时,我得到了

HTTP Status 400 - The request sent by the client was syntactically incorrect ().

答案1

小编典典

我正在添加此答案,以便您可以接受它,正如Bozho建议的那样:)

HTML中似乎有一个问题: <input type="text name="text">

将其更改为 <input type="text" name="text">并尝试。

我认为语法上不正确意味着在@RequestParam批注中指定的名称与请求参数名称不匹配…可能是由于上述HTML错误。

java stream如何实现guava的partition

java stream如何实现guava的partition

List<String> list1 = new ArrayList<>();
list1.add("a1");list1.add("a2");list1.add("a3");list1.add("a4");list1.add("a5");list1.add("a6");list1.add("a7");list1.add("a8");
List<List<String>> partition = Lists.partition(list1, 3);
List<String> collect = list1.stream().limit(2).collect(Collectors.toList());

java8怎么实现这个

List<List<String>> partition = Lists.partition(list1, 3);

关于Spring中的@RequestParam如何处理Guava的Optional?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于@RequestParam 和 @RequestBody 的在 spring boot 中的用法、@RequestParam 注解使用:Name for argument type [java.lang.String] not available, and parameter name inf...、Java Spring @RequestParam JSP、java stream如何实现guava的partition等相关知识的信息别忘了在本站进行查找喔。

本文标签: