2017-04-19 7 views
9
@GetMapping("item") 
public @ResponseBody String get(@ModelAttribute Item item) 

Item विशेषताओं(वसंत MVC/जैक्सन) @ModelAttribute को मानचित्रण क्वेरी पैरामीटर: SNAKE_CASE को LOWERCASE_WITH_UNDERSCORE विफल रहता है

  • name

  • itemType

जब मैं है /item?name=foo&item_type=bar का उपयोग करें item केवल nameitemType साथ नहीं साथ आबादी वाले हो जाता है।

मैंने itemType विशेषता item_type से मैप किए गए गुण प्राप्त करने के लिए चीजों का एक गुच्छा करने की कोशिश की।

  • जोड़ा गया @JsonProperty ("item_type") Item के itemType विशेषता के अंदर। Described here
  • एक JackonConfiguration PropertyNamingStrategy.SNAKE_CASE को propertyNamingStrategy सेट है कि जोड़ा गया। Described here
  • जोड़ा गया spring.jackson.property-नामकरण-रणनीति मेरी स्प्रिंग बूट करने के लिए = SNAKE_CASE फ़ाइल application.properties। Described here
  • Item वर्ग स्तर पर PropertyNamingStrategy जोड़ा गया। Described here

मैं यह कैसे हल कर सकते हैं?

Btw

। मुझे केवल Item के आउटगोइंग JSON क्रमबद्धता के लिए यह समस्या नहीं है।


अद्यतन 04/24/17:

एक न्यूनतम नमूना नीचे समस्या प्रदर्शित करने के लिए: /item पर जाकर जब आप कि 'outgoing' JSON क्रमबद्धता काम करता है देखेंगे लेकिन यह करता है /item/search?name=foo&item_type=bar पर जाकर जब 'आने वाले' JSON deserialization के लिए काम नहीं करते हैं।

आइटम

package sample; 

import java.io.Serializable; 

import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy; 
import com.fasterxml.jackson.databind.annotation.JsonNaming; 

@JsonNaming(SnakeCaseStrategy.class) 
public class Item implements Serializable { 
    private String name; 
    @JsonProperty("item_type") 
    private String itemType; 
    public Item() { } 
    public Item(String name, String itemType) { 
     this.name = name; 
     this.itemType = itemType; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getItemType() { 
     return itemType; 
    } 
    public void setItemType(String itemType) { 
     this.itemType = itemType; 
    } 
} 

ItemController.java

package sample; 

import org.springframework.data.domain.Page; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
@RequestMapping("/item") 
public class ItemController { 
    @GetMapping("search") 
    public @ResponseBody Page<Item> search(@ModelAttribute Item probe) { 
     System.out.println(probe.getName()); 
     System.out.println(probe.getItemType()); 
     //query repo by example item probe here... 
     return null; 
    } 
    @GetMapping 
    public Item get() { 
     return new Item("name", "itemType"); 
    } 
} 

JacksonConfiguration.java

package sample; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; 

import com.fasterxml.jackson.databind.PropertyNamingStrategy; 

@Configuration 
public class JacksonConfiguration { 
    @Bean 
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { 
     return new Jackson2ObjectMapperBuilder() 
       .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); 
    } 
} 

SampleBootApplication.java

package sample; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication 
public class SampleBootApplication { 
    public static void main(String[] args) { 
     SpringApplication.run(SampleBootApplication.class, args); 
    } 
} 

application.properties

logging.level.org.springframework=INFO 
spring.profiles.active=dev 
spring.jackson.property-naming-strategy=SNAKE_CASE 

पोम।एक्सएमएल

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>sample</groupId> 
    <artifactId>sample</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 
    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.5.2.RELEASE</version> 
    </parent> 
    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
     <java.version>1.8</java.version> 
    </properties> 
    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-actuator</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-cache</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-thymeleaf</artifactId> 
      <exclusions> 
       <exclusion> 
        <groupId>nz.net.ultraq.thymeleaf</groupId> 
        <artifactId>thymeleaf-layout-dialect</artifactId> 
       </exclusion> 
      </exclusions> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-devtools</artifactId> 
      <scope>runtime</scope> 
     </dependency> 
     <dependency> 
      <groupId>org.hsqldb</groupId> 
      <artifactId>hsqldb</artifactId> 
      <scope>runtime</scope> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
       <executions> 
        <execution> 
         <!-- Spring Boot Actuator displays build-related information if a META-INF/build-info.properties 
          file is present --> 
         <goals> 
          <goal>build-info</goal> 
         </goals> 
         <configuration> 
          <additionalProperties> 
           <encoding.source>${project.build.sourceEncoding}</encoding.source> 
           <encoding.reporting>${project.reporting.outputEncoding}</encoding.reporting> 
           <java.source>${maven.compiler.source}</java.source> 
           <java.target>${maven.compiler.target}</java.target> 
          </additionalProperties> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
</project> 
+0

यदि आपके पास कहीं @EnableWebMvc एनोटेशन है, तो इसे हटा दें। रेफरी: http://stackoverflow.com/questions/40649177/jackson-is-ignoring-spring-jackson-properties-in-my-spring-boot-plication –

+0

कोई भी नहीं है। – hansi

उत्तर

2

स्प्रिंग की मदद के बिना जैक्सन काम कर रही द्वारा हल से है।

@GetMapping("search") 
public @ResponseBody Page<Item> search(@RequestParam Map<String,String> params) { 
    ObjectMapper mapper = new ObjectMapper(); 
    //Not actually necessary 
    //mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); 
    Item probe = mapper.convertValue(params, Item.class); 

    System.out.println(probe.getName()); 
    System.out.println(probe.getItemType()); 
    //query repo by example item probe here... 
    return null; 
} 
1

हैं/मद? नाम = foo & item_type = बार यूआरएल प्रपत्र के किसी भी प्रकार और से नहीं आ रही है तो आप सिर्फ और नाम प्राप्त करना चाहते हैं तो अपने url से item_type हैं, तो

यह प्रयास करें :

@GetMapping("item/{name}/{item_type}") 
public String get(@PathVariable("name") String 
myName,@PathVariable("item_type") String myItemType){ 

//Do your business with your name and item_type path Variable 

} 

आप कई पथ चर है, तो भी आप bellow दृष्टिकोण के रूप में अच्छी तरह से कोशिश कर सकते हैं, यहाँ सब पथ चर मानचित्र में हो जाएगा,

@GetMapping("item/{name}/{item_type}") 
public String get(@PathVariable Map<String,String> pathVars){ 

//try something like 
    String name= pathVars.get("name"); 
    String type= pathVars.get("item_type"); 

//Do your business with your name and item_type path Variable 

} 

नोट: यदि इस फार्म के किसी भी प्रकार तो बेहतर इस्तेमाल पोस्ट के बजाय प्राप्त

+0

मैंने इन दो विकल्पों पर विचार किया, लेकिन मैं काम करने के लिए '@ ModelAttribute' मैपिंग प्राप्त करना चाहता हूं। मेरे पास पैरामीटर के बहुत सारे (> 30) हैं और सादगी के लिए इसे छोटा रखा है। – hansi

+0

हमें @ModelAttribute बनाने के लिए, अपने फॉर्म के इनपुट टैग के रूप में बिल्कुल उसी दायर नाम के साथ एक pojo cals बनाएं (मुझे लगता है कि आप फॉर्म का उपयोग कर रहे हैं) नाम विशेषता, तो वसंत आपके लिए अंतर्निहित डेटा बाइंडिंग करेगा और अतिरिक्त करने की आवश्यकता नहीं होगी चीज – KAmit

+0

जैसा कि मेरे प्रश्न में वर्णित है: यह वही है जो मैंने किया है। यह क्षेत्र के नामों के मामले को बदलने के लिए अंडरस्कोर की बात आती है जब यह अपेक्षित काम नहीं कर रहा है। – hansi

1

तुम भी उपयोग कर सकते हैं HttpServletRequest वस्तु पैरामीटर

@GetMapping("search") 
    public @ResponseBody Page<Item> search(HttpServletRequest request) { 
     Item probe = new Item(); 
     probe.setName(request.getParameter('name')); 
     probe.setItemType(request.getParameter('item_type')); 

     System.out.println(probe.getName()); 
     System.out.println(probe.getItemType()); 
     //query repo by example item probe here... 
     return null; 
    } 
+0

यह समस्या का समाधान नहीं करता है। वहां बड़ी संख्या में पैरामीटर हैं और मैं उन सभी को कड़ी मेहनत नहीं करना चाहता हूं। (बक्षीस को स्वत: असाइन किया गया है) – hansi

+0

मैंने कहा कि आप "इसका भी उपयोग" कर सकते हैं यह सबसे अच्छा समाधान नहीं है! मेरे लिए मैं अपने सभी कामों के लिए POST का उपयोग करता हूं और मैं @RequestParams को प्राप्त करता हूं लेकिन कभी-कभी हमें अनुरोध से पैरा प्राप्त करने की आवश्यकता होती है ... –

2

पाने के लिए आप डिफ़ॉल्ट पैरामीटर मानचित्रण के साथ परेशानी हो रही है, या आप जटिल निर्माण तर्क के साथ एक वस्तु है, तो आप को लागू करने की कोशिश कर सकते एक HandlerMethodArgumentResolver। यह आपको अपनी कक्षा को नियंत्रक विधि तर्क के रूप में उपयोग करने की अनुमति देगा और मैपिंग कहीं और किया जाएगा। ,

@Configuration 
public class WebAppConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { 
     argumentResolvers.add(new ItemArgumentResolver()); 
    } 

} 

अब आप एक नियंत्रक विधि तर्क के रूप में Item वर्ग का उपयोग कर सकते प्रत्येक विधि में प्रत्येक वस्तु का दृष्टांत के बिना:

public class ItemArgumentResolver implements HandlerMethodArgumentResolver { 

    @Override 
    public boolean supportsParameter(MethodParameter methodParameter) { 
     return methodParameter.getParameterType().equals(Item.class); 
    } 

    @Override 
    public Object resolveArgument(MethodParameter methodParameter, 
           ModelAndViewContainer modelAndViewContainer, 
           NativeWebRequest nativeWebRequest, 
           WebDataBinderFactory webDataBinderFactory) throws Exception { 
     Item item = new Item(); 
     item.setName(nativeWebRequest.getParameter("name")); 
     item.setItemType(nativeWebRequest.getParameter("item_type")); 
     return item; 
    } 

} 

तो फिर आप अपने वेब अनुप्रयोग विन्यास में में पंजीकरण कराना होगा

@RequestMapping("/items") 
public @ResponseBody String get(Item item){ ... } 
संबंधित मुद्दे