如果您对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?
- @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?
@RequestMapping(value = "/contact.html", method = RequestMethod.POST)public final ModelAndView contact( @RequestParam(value = "name", required = false) Optional<String> name) {
如果不需要参数值并且什么也不发送,Spring如何@RequestMapping
处理Guava库中的Optional
from
?
那将会:
- 设置
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 中的用法
一、现象
由于项目是前后端分离,因此后台使用的是 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...
详细错误信息
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
当前控制器代码:
@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
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等相关知识的信息别忘了在本站进行查找喔。
本文标签: